我想创建一个页面,在左边我有固定视图(一些过滤器),它们应用于右侧的结果.
例如,左侧是根据流派,标题,创建年份过滤电影的过滤器....右侧是不同的图表和表格,根据所选的过滤器进行更新.
所以我想在左边有一个固定的视图,然后在右边有一个根据路线改变的出口.
这是正确的方法吗?如果是,我无法弄清楚如何将过滤器更改传达给右侧的控制器.
这个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')
});
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
Wil*_*ney 25
我已经为你创建了一个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' })
]);
}
});
Run Code Online (Sandbox Code Playgroud)
很有可能这个代码将被替换为您的后端Ruby/PHP的某种AJAX调用.但就目前而言,我们将IndexRoute负责设置控制器(因此setupController).这个责任也可以在控制器本身上,并且抽象出AJAX调用可能是一个好主意,因为你将有许多类似的AJAX调用.
您也可以决定使用Ember的DataStore,它将再次改变控制器的实现.
索引控制器
接下来我们将设置我们的IndexController(我们SongsController真的是),我们希望这个控制器有两个职责:
为此,我们创建了一个计算属性来过滤掉内容,因为我们不想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')
});
Run Code Online (Sandbox Code Playgroud)
该excludeGenres会采取类别对象的数组.例如,如果其中包含"Post Rock" excludeGenres,那么我们将不会显示任何"Post Rock"相关歌曲,但如果它不存在,那么我们将向他们展示!在IndexController没有责任维护这个数组,但它确实有它的过滤时,该阵列的内容负责更新.
流派控制器
也许是我们这个小应用程序中最令人困惑的控制器,因为它实际上并没有自己的任何内容,而是取决于它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);
}
});
Run Code Online (Sandbox Code Playgroud)
流派控制器的职责可以定义如下:
content数组IndexController并在其长度变化时获取唯一的类型名称;excludeGenres在用户单击列表中的类型以包含/排除数组时填充数组.要toggle调用该方法,我们需要在我们的流派视图中指定一个动作,以便在单击时调用它:<a {{action "toggle" genre}}>{{genre}}</a>.现在,只要用户点击某个流派,toggle就会调用该方法,并将流派名称作为第一个参数传递.
一旦我们进入该toggle方法,它将确定该类型是否已被排除.如果它被排除,那么它将被删除,反之亦然.一旦我们添加/删除了类型,filteredContent计算属性将再次触发,索引视图将无缝更新.
究其原因,GenresController实际上并没有自己的内容是,它似乎愚蠢的管理两个content阵列当两个有关系.由于类型可以从应用程序中存在的歌曲中确定,控制器可以从该列表中收集信息,并且只需提取它所需的信息 - 在我们的例子中,类型.
这样,如果添加/删除歌曲,则可以使类型列表保持同步.
结论
但是,我认为原始问题的答案是,为了使控制器彼此通信,您需要指定它所需要的内容(使用needs).
| 归档时间: |
|
| 查看次数: |
8043 次 |
| 最近记录: |