2012-04-03 54 views
32

我想將不同的對象存儲在同一個控制器內容數組中,並使用適當的視圖模板呈現每個對象,但理想情況下是相同的視圖。使用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> 

我的頭幾個測試到允許不同的對象類型結束了的「簡單行預覽」中的條件載荷 - 它看上去太可怕了!

是否有任何方式來動態控制迭代通過我的內容數組時使用的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> 

回答

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/

+2

這是一個很好的答案,但遺憾的是,這種情況下視圖不是通過一個把手幫手添加的,而是作爲一個通過ember自動拾取的類。在這種情況下,你無法訪問'content'和'controller'(這裏討論:http://stackoverflow.com/questions/15337065/how-to-get-any-controller-instance-from-init-對的一視點方法)。在這種情況下,我的解決方案是有一個方法觀察'controller.content',並通過'this.set('currentView',view)'在這個函數中相應地設置視圖' – vanthome 2013-12-21 16:56:57

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') 
}); 
+0

注意:這不起作用。當視圖被破壞時,視圖有時會嘗試渲染,並引發錯誤。 – 2014-12-18 04:15:56