我想创建一个页面,该页面的左侧有固定 View (一些过滤器),这些 View 应用于右侧的结果。
例如,左侧的过滤器可按流派,标题,创作年份...来过滤电影。
右侧是不同的图表和表格,它们会根据所选过滤器进行更新。
所以我当时想在左边有一个固定的 View ,然后在右边有一个可以根据路线改变的导出。
这是正确的方法吗?如果是这样,我不知道如何将过滤器更改传达给右侧的 Controller 。
此JSFiddle显示类似的设置:http://jsfiddle.net/DEHcK/2/
在ContentRoute-> setupController中,我获得了NavigationController的实例,但是后来我不知道如何获取对someValue的更改。
在上面的示例中,ContentController如何在NavigationController中获取对someValue的更改?
这是实现我在ember中描述的应用程序的正确方法吗?
JavaScript:
window.App = Ember.Application.create();
App.Router.map(function () {
this.route('content');
});
App.ContentRoute = Ember.Route.extend({
setupController: function (controller) {
controller.set('navigationController', this.controllerFor('navigation'));
}
});
App.ContentController = Ember.ObjectController.extend({
navigationController: null,
observerOfSomeValue: function () {
this.set('observedValue', this.get('navigationController.someValue'));
}.observes('navigationController', 'navigationController.someValue'),
observedValue: null
});
App.IndexRoute = Ember.Route.extend({
redirect: function () {
this.transitionTo('content');
}
});
App.NavigationView = Ember.View.extend({
init: function () {
this._super();
this.set('controller', this.get('parentView.controller').controllerFor('Navigation'));
},
templateName: "navigation"
});
App.NavigationController = Ember.ObjectController.extend({
someValue: 'xx',
observedValue: null,
observerOfSomeValue: function () {
this.set('observedValue', this.someValue);
}.observes('someValue')
});
HTML:
<script type="text/x-handlebars" data-template-name="application" >
<div>
{{view App.NavigationView}}
</div>
<div>
{{ outlet }}
</div>
</script>
<script type="text/x-handlebars" data-template-name="navigation" >
Change {{view Ember.TextField valueBinding="controller.someValue"}}
<div>observed value in same view: {{controller.observedValue}}</div>
</script>
<script type="text/x-handlebars" data-template-name="content" >
<div style="margin-top: 2em">
observed value in another view: {{observedValue}}
</div>
</script>
最佳答案
我继续了created you a JSFiddle并提供了您所追求的基本实现。我认为值得进行所有操作,以便您可以掌握Ember。
路由器
现在,我们仅配置IndexRoute
,在其中存储{{outlet}}
的所有歌曲。
App.IndexRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('content', [
Ember.Object.create({ title: 'Stairway to Heaven', genre: 'Metal' }),
Ember.Object.create({ title: 'Ratts of the Capital', genre: 'Post Rock' }),
Ember.Object.create({ title: 'Wonderwall', genre: 'Brit Pop' }),
Ember.Object.create({ title: 'Last Flowers', genre: 'Indie Rock' })
]);
}
});
这个代码很有可能会被后端Ruby/PHP的某种AJAX调用所取代。暂时,我们将给
IndexRoute
负责设置 Controller 的职责(因此setupController
)。这个责任也应该由 Controller 本身承担,并且抽象出AJAX调用可能是一个好主意,因为您将有许多类似的AJAX调用。您也可以决定使用use Ember's DataStore,它将再次更改 Controller 的实现。
索引 Controller
接下来,我们将设置我们的
IndexController
(这实际上是我们的SongsController
),我们希望此 Controller 承担两项职责:为此,我们创建了一个computed property来过滤内容,因为我们实际上并不希望直接操作特殊的
content
数组。App.IndexController = Ember.ArrayController.extend({
content: [],
excludeGenres: [],
filteredContent: function() {
var excludeTheseGenres = this.get('excludeGenres').mapProperty('genre');
return this.get('content').filter(function(model) {
return Boolean(jQuery.inArray(model.get('genre'), excludeTheseGenres) === -1);
});
}.property('excludeGenres.length', 'content.length')
});
excludeGenres
将采用一个流派对象数组。例如,如果excludeGenres
中包含“Post Rock”,那么我们将不会显示任何与“Post Rock”相关的歌曲,但是如果不存在,我们将显示它们! IndexController
不负责维护此数组,但确实负责在更新此数组时过滤其内容。流派 Controller
在我们的小应用程序中,也许是最令人困惑的 Controller ,因为它实际上没有自己的任何内容,而是取决于
IndexController
的内容。App.GenresController = Ember.ObjectController.extend({
needs: ['index'],
genres: function() {
return this.get('controllers.index').mapProperty('genre').uniq();
}.property('controllers.index.length'),
toggle: function(genreName) {
var indexController = this.get('controllers.index'),
genres = indexController.get('excludeGenres'),
genre = indexController.findProperty('genre', genreName);
if (genres.findProperty('genre', genreName)) {
genres.removeObject(genre);
return;
}
genres.pushObject(genre);
}
});
体裁负责人的职责可以这样定义:
content
的IndexController
数组,并在长度改变时获取唯一的流派名称。 excludeGenres
数组。 要调用
toggle
方法,我们需要在流派 View 中指定一个操作以在单击时调用它:<a {{action "toggle" genre}}>{{genre}}</a>
。现在,每当用户单击一个流派时,就会调用toggle
方法,并将流派名称作为第一个参数传递。一旦进入
toggle
方法,它将确定该类型是否已被排除。如果将其排除在外,则将其删除,反之亦然。一旦添加/删除了流派,就将再次触发ojit_code计算属性,并且索引 View 将无缝更新。filteredContent
实际上没有自己的内容的原因是,当两个GenresController
数组有关系时,管理两个content
数组似乎很愚蠢。由于可以根据应用程序中存在的歌曲确定流派,因此 Controller 可以从该列表中收集信息,然后提取所需的信息(在我们的示例中为流派)。这样,如果添加/删除了歌曲,则流派列表可以保持同步。
结论
我认为您的原始问题的答案是,为了使 Controller 之间能够相互通信,您需要指定需要(使用
needs
)。
关于ember.js - 如何在Ember.js中的 Controller 之间进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14862973/