0

我一直遇到一个棘手的情况:在车把模板中需要一个新的控制器实例。

这是我的情况的一个简短示例。(请原谅我使用咖啡脚本)

在 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

{{#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}}

我知道这很糟糕,但我想不出更好的方法。有人,请帮助我看到光明!

4

2 回答 2

0

这个问题提出了一个关于 ArrayControllers、CollectionViews、Models 和 ObjectControllers 的重要且长期存在的问题。

在撰写本文时,我对 Ember 内部工作原理的了解有限。但是,我可以更简洁地改写我的问题如下:

给定一个模型的 ArrayController、CollectionView 和实例控制器,如何利用itemControllerClassArrayController 的属性来迭代其内容并将每个项目包装在一个唯一的(即非单例)实例中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可以使用 a 的情况:

{{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具有属性itemControllerlookupItemController定义。

不幸的是,在这种情况下,我们失去了使用 CollectionView 的tagNameoremptyView属性的好处。希望如果创建了“ArrayView”,它将为这种情况带来两全其美的效果!

于 2013-09-18T13:59:47.873 回答
0

您可以itemControllereach循环中显式设置。

{{#each myFooArray itemController="foo"}}
  Hi! My attr is {{attr}}
{{/each}}
于 2013-09-13T06:45:24.957 回答