假设我的应用程序中有两个对象:1)主题,2)类别。
Topic
有一条路线/topic/:topic_id
Categories
没有网址路由。它包含主题可以包含的所有可用类别的列表。
在Topic
的页面上,我想显示所有类别的列表,同时突出显示该主题所属的类别(“有效”类别)
我最初使用组件解决了这个问题(为了简洁起见,删除了大量代码):
组件模板:
(通过每个类别并列出它们。如果当前的类别处于活动状态,它会这样说。)
<script type="text/x-handlebars" id="components/category-list">
{{#each categories}}
{{#if this.active}} Active -> {{/if}}
{{this.name}}
<br />
{{/each}}
</script>
组件对象:
(通过CategoriesController浏览模型,通过从{{category-list}}组件助手传入的“当前”参数将一个类别标记为该主题的当前活动类别
App.CategoryListComponent = Ember.Component.extend({
tagName: '',
didInsertElement: function () {
var categories = App.CategoriesController;
var current = this.get('current').get('id');
categories.get('content').forEach(function (c) {
if (c.id === current) {
c.active = true;
}
});
this.set('categories', categories);
}.observes('current')
});
显示类别列表:
在主题视图中('category'是Topic的属性,说明主题所属的类别):
{{category-list current=category}}
这一切都有效,但我觉得这不是解决问题的正确方法。组件将我视为应该非常可重用的东西,而这实际上只是一个视图的封装部分。
现在我尝试将类别列表用作视图。所以现在而不仅仅是一个Component,我有一个CategoriesRoute(虽然没有挂在路由器中),一个CategoriesController和一个CagetoriesView。
当Topic资源加载时,它会使用加载的模型数据设置类别控制器:
App.TopicRoute = Ember.Route.extend({
model: function (params) {
return Em.RSVP.hash({
topic: this.store.find('topic', params.topic_id),
categories: this.store.find('category')
});
},
setupController: function (controller, context) {
this._super(controller, context.topic);
this.controllerFor('categories').set('model', context.categories);
}
});
CategoriesController只是一个标准的数组控制器:
App.CategoriesController = Ember.ArrayController.extend({});
CategoriesView也非常简单:
App.CategoriesView = Ember.View.extend({
templateName: 'categories',
tagName: ''
});
最后是类别模板:
<script type="text/x-handlebars" id="components/category-list">
{{#each categories}}
{{this.name}}
<br />
{{/each}}
</script>
我在主题模板中使用{{render}}帮助器呈现列表:
{{render "categories" }}
以上似乎在显示类别列表方面工作正常。但是,我无法弄清楚如何告诉视图哪个类别处于活动状态(主题所在的类别)。
我在互联网上环顾四周,看起来{{render}}帮助使用了以允许可选的选项哈希(这就是我在第一次使用Component解决问题的方法尝试),但似乎已在最近的Ember版本中删除。
我找到了一个StackOverflow条目,它提到了我自己的{{render}}帮助器,但它看起来就是动态地改变模型,或者那种性质的东西。我想保留模型支持类别视图,我只需要能够通过Topic.category属性告诉它哪个类别是活动的。
或者,我的第一次尝试是更好的解决方案吗?我对Ember很新,所以我不确定这里最好的策略是什么。我的直觉告诉我,我应该使用我的第二次尝试,而不是第一次尝试,但我不是肯定的。
非常感谢任何帮助。
答案 0 :(得分:1)
你说的是组件必须可以在任何地方重复使用,并且不应该绑定到任何特定的控制器。我会用这个视图。我会这样做,我会有一个
App.CategoriesController = Em.ArrayController.extend({
itemController: 'category',
//some other stuff here
});
对于类别,然后有一个名为
的itemControllerApp.CategoryController = Em.ObjectController.extend({
setActiveState: function() {
if (this.get('parentController.current.id') === this.get('content.id')) {
this.set('active', true);
}
}
});
在模板中,您可以说
{{#each category in categories}}
{{category.name}}
{{/each}}