使用Ember.js按模型类型/对象值选择视图模板

时间:2012-04-03 18:20:12

标签: javascript ember.js

我想在同一控制器内容数组中存储不同的对象,并使用适当的视图模板渲染每个对象,但理想情况下是相同的视图。

我正在使用下面的代码输出列表对象。它们目前是相同的,但我希望能够使用不同的。

<script type="text/x-handlebars">
  {{#each App.simpleRowController}}
    {{view App.SimpleRowView class="simple-row" contentBinding="this"}}
  {{/each}}
</script>

视图的简化版本如下。我没有包含的其他功能可以用于任何对象,无论模型如何。所以我理想情况下会有一个观点(虽然我已经阅读了一些关于mixin的文章,如果不是这样的话可以提供帮助)。

<script>
  App.SimpleRowView = Em.View.extend({
    templateName: 'simple-row-preview',
  });
</script>

我允许不同对象类型的前几个测试最终在'simple-row-preview'中出现了大量条件 - 它看起来很糟糕!

有没有办法动态控制迭代我的内容数组时使用的templateName或视图?

更新

非常感谢两位受访者。视图中使用的最终代码如下所示。我的一些模型很相似,我喜欢能够在我的应用程序中切换模板(或某种“状态”)的想法。

<script>
  App.SimpleRowView = Em.View.extend({
    templateName: function() {
      return Em.getPath(this, 'content.template');
    }.property('content.template').cacheable(),
    _templateChanged: function() {
      this.rerender();
    }.observes('templateName'),
    // etc.
  });
</script>

2 个答案:

答案 0 :(得分:102)

您可以将templateName设为属性,然后根据内容确定要使用的模板。

例如,这使用instanceof根据对象类型设置模板:

App.ItemView = Ember.View.extend({
    templateName: function() {
        if (this.get("content") instanceof App.Foo) {
            return "foo-item";
        } else {
            return "bar-item";
        }
    }.property().cacheable()
});

以上是上述工作示例的小提琴:http://jsfiddle.net/rlivsey/QWR6V/

答案 1 :(得分:16)

基于@rlivsey的解决方案,我添加了在属性更改时更改模板的功能,请参阅http://jsfiddle.net/pangratz666/ux7Qa/

App.ItemView = Ember.View.extend({
    templateName: function() {
        var name = Ember.getPath(this, 'content.name');
        return (name.indexOf('foo') !== -1) ? 'foo-item' : 'bar-item';
    }.property('content.name').cacheable(),

    _templateChanged: function() {
        this.rerender();
    }.observes('templateName')
});