我遇到了一个棘手的问题:我需要在手柄模板中使用新的控制器实例。
以下是我的情况的简要示例。 (请原谅我使用coffeecript)
在恩伯,我有一个模特:
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
中的项目:
{{#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}}
我知道这很糟糕,但我想不出更好的方法。有人,请帮我看看光!
答案 0 :(得分:0)
您可以在itemController
循环中明确设置each
。
{{#each myFooArray itemController="foo"}}
Hi! My attr is {{attr}}
{{/each}}
答案 1 :(得分:0)
这个问题对ArrayControllers,CollectionViews,Models和ObjectControllers提出了一个重要且长期存在的问题。
在撰写本文时,我对Ember内部运作的了解有限。但是,我可以更简洁地将我的问题改写如下:
给定模型的ArrayController,CollectionView和实例控制器,如何利用ArrayController的
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
这些函数的目的是将内容作为控制器的数组返回但是如何?
第一个要求是直接使用ArrayController作为循环中的内容。不幸的是,事情开始分崩离析。
您可能认为只能使用CollectionView
:
{{view myCollectionView controllerBinding=myArrayController}}
或
{{view myCollectionView contentBinding=myArrayController}}
但遗憾的是情况并非如此。在您在另一个Controller的路径上渲染Controller的情况下更是如此。 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',它将为这种情况带来两全其美!