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

joe*_*der 32 javascript ember.js

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

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

<script type="text/x-handlebars">
  {{#each App.simpleRowController}}
    {{view App.SimpleRowView class="simple-row" contentBinding="this"}}
  {{/each}}
</script>
Run Code Online (Sandbox Code Playgroud)

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

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

我允许不同对象类型的前几个测试最终在"简单行预览"中遇到了大量条件 - 它看起来很糟糕!

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

UPDATE

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

<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>
Run Code Online (Sandbox Code Playgroud)

rli*_*sey 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()
});
Run Code Online (Sandbox Code Playgroud)

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

  • 这是一个非常好的答案,但不幸的是,这种情况下,视图不是通过把手助手添加的,而是作为一个由ember自动拾取的类.在这种情况下,您无法访问`content`或`controller`(在此处讨论:http://stackoverflow.com/questions/15337065/how-to-get-any-controller-instance-from-init-对的一视点方法).在这种情况下我的解决方案是让一个方法观察`controller.content`并通过`this.set('currentView',view)在这个函数中相应地设置视图. (2认同)

pan*_*atz 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')
});
Run Code Online (Sandbox Code Playgroud)