簡體   English   中英

如何在車把模板中獲取模型控制器的實例?

[英]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具有定義的屬性itemControllerlookupItemController

不幸的是,在這種情況下,我們失去了使用CollectionView的tagNameemptyView屬性的好處。 希望如果創建了“ ArrayView”,它將為這種情況帶來兩全其美的感覺!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM