假设我的应用程序中有两个对象:1)主题,2)类别。
Topic
有一个路由/topic/:topic_id
类别
没有URL路由。它包含主题可以所在的所有可用类别的列表。
在Topic
页面上,我想显示所有类别的列表,同时突出显示该主题所属的类别(“活动”类别)
我最初使用如下组件解决了这个问题(为了简洁起见删除了很多代码):
组件模板:
(遍历每个类别并列出它们。如果当前一个是活动的,它会这样说。)
<script type="text/x-handlebars" id="components/category-list">
{{#each categories}}
{{#if this.active}} Active -> {{/if}}
{{this.name}}
<br />
{{/each}}
</script>
组件对象:
(通过类别控制器遍历模型,通过从{{diage-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-list current=category}}
这一切都是可行的,但我有一种感觉,这不是解决问题的正确方法。组件在我看来应该是非常可重用的,而这实际上只是一个视图的封装部分。
现在我尝试使用类别列表作为视图。所以现在不仅仅是一个组件,我有一个类别路由(虽然没有连接在路由器中)、一个类别控制器和一个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);
}
});
类别控制器只是一个标准的阵列控制器:
App.CategoriesController = Ember.ArrayController.extend({});
类别视图也很简单:
App.CategoriesView = Ember.View.extend({
templateName: 'categories',
tagName: ''
});
最后是类别模板:
<script type="text/x-handlebars" id="components/category-list">
{{#each categories}}
{{this.name}}
<br />
{{/each}}
</script>
我正在主题模板中使用{{del}}助手渲染列表:
{{render "categories" }}
以上似乎在显示类别列表方面工作得很好。然而,我不知道如何告诉视图哪个类别是活动的(主题所在的类别)。
我在互联网上看了看,它看起来像{{渲染}}助手用来允许可选选项散列(这是我第一次尝试用组件解决问题的方式),但它似乎在Ember的一些最新版本中被删除了。
我找到了一个StackOverflow条目,其中提到了制作我自己的{{渲染}}助手,但它看起来像是动态更改模型,或者类似的东西。我想保留模型作为类别视图的后盾,我只需要能够通过主题.类别属性告诉它哪个类别是活动的。
或者,我的第一次尝试是更好的解决方案吗?我对灰烬很陌生,所以我不确定这里的最佳策略是什么。我的直觉告诉我,我应该使用第二次尝试,而不是第一次,但我不积极。
任何帮助都非常感谢。
你说得对,组件必须在任何地方都可重用,不应该绑定到任何特定的控制器。我会为此使用视图。我要做的是,我会有一个
App.CategoriesController = Em.ArrayController.extend({
itemController: 'category',
//some other stuff here
});
用于类别,然后有一个名为
App.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}}