[英]How can I get an instance of a model's controller inside a handlebars template?
我一直遇到一個棘手的情況:在車把模板中需要一個控制器的新實例。
這是我情況的一個簡短示例。 (請原諒我使用咖啡餅)
在Ember中,我有一個模型:
App.Foo = DS.Model.extend
attr: DS.attr()
...
我是從端點等加載的。然后放入數組控制器:
App.FooArray = Ember.ArrayController.extend
###*
* Array of App.Foo
* @type {Array}
*/
content:
method: ->
...
最后,我有一個用於該模型的“實例”控制器,該控制器實現了進一步的方法(即,這不是路由器級別的單例控制器,而是一個裝飾器(或代理),它通過添加的方法和事件來擴充模型處理程序):
App.FooController = Ember.ObjectController.extend
###*
* Content
* @type {App.Foo}
*/
content: null
action: ->
...
在車把中,我想遍歷App.FooArray
中的App.FooArray
:
{{#each myFooArray}}
Hi! My attr is {{attr}}
{{/each}}
等等。這對於參數等非常有用。
但是,當我想使用動作(或其他屬於FooController的屬性)時,麻煩就開始了
{{#each myFooArray}}
Hi! My attr is {{attr}} <a {{action 'action'}}>Action me!</a>
{{/each}}
突然我的動作不起作用。 這是因為動作助手沒有將動作應用於“ this”,而是應用於更高級別的控制器,甚至可能在路由級別!
因此,要解決此問題,我需要傳遞一個目標(即控制器):
{{action 'action' target=**********}}
好吧,我想要的控制器是App.FooController
的實例。 到現在為止,我一直在實例化模型中的控制器(糟糕!):
App.Foo = DS.Model.extend
attr: DS.attr()
...
attrn: DS.attr()
myController: Ember.computed (->
App.FooController.create
content: this
)
因此,迭代如下:
{{#each myFooArray}}
Hi! My attr is {{attr}} <a {{action 'action' target=myController}}>Action me!</a>
{{/each}}
我知道這很不好,但是我想不出更好的方法。 有人,請幫我看看光!
您可以在each
循環中顯式設置itemController
。
{{#each myFooArray itemController="foo"}}
Hi! My attr is {{attr}}
{{/each}}
這個問題提出了一個關於ArrayControllers,CollectionViews,Models和ObjectControllers的重要而長期的問題。
在撰寫本文時,我對Ember內部運作的了解有限。 但是,我可以更簡潔地重新表述我的問題,如下所示:
給定一個模型的
itemControllerClass
,CollectionView和實例控制器,如何利用itemControllerClass
屬性來迭代其內容並將每個項目包裝在itemController
的唯一(即非單個)實例中?
事實證明,這個問題是長期存在的,該解決方案回顯了@ jeremy-green,但我將在這里繼續介紹。
不過首先:封裝問題的Ember支持線程: https : //github.com/emberjs/ember.js/issues/1637
我認為那里的討論非常明確地指出在某些情況下需要非單控制器。
同樣,以下是ArrayController的文檔,該文檔指示ArrayController上存在“ itemController”屬性: http ://emberjs.com/api/classes/Ember.ArrayController.html#property_itemController
進一步研究文檔,您還將注意到“ lookupItemController”功能的存在: http ://emberjs.com/api/classes/Ember.ArrayController.html#method_lookupItemController
這些函數的明確目的是將內容作為Controllers數組返回,但是如何?
好吧,第一個要求是直接將ArrayController用作循環中的內容。 不幸的是,這是事情開始崩潰的地方。
您可能會認為,可以使用CollectionView
只是一種情況:
{{view myCollectionView controllerBinding=myArrayController}}
要么
{{view myCollectionView contentBinding=myArrayController}}
但是不幸的是事實並非如此。 在要在另一個控制器的路徑上渲染控制器的情況下,更是如此。 CollectionView不會保留ArrayController及其“ itemControllerClass”之間的關系。
如@ jeremy-green指出的,使這項工作有效的唯一方法:
{{#each myFooArray itemController="foo"}}
Hi! My attr is {{attr}}
{{/each}}
一個更完整的示例是:
<ol class="foo-item-list">
{{#each controllers.foo_items}}
<li>{{ view "foo" }}</li>
{{/each}}
</ol>
其中App.FooItemsController
具有定義的屬性itemController
或lookupItemController
。
不幸的是,在這種情況下,我們失去了使用CollectionView的tagName
或emptyView
屬性的好處。 希望如果創建了“ ArrayView”,它將為這種情況帶來兩全其美的感覺!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.