簡體   English   中英

ember.js |在一個組件操作上通知其他組件

[英]ember.js | notify other components on one component action

Ember的指南組件部分有一個Post Summary Component的演示,點擊一個Post Summery標題打開它下面的內容。

我想添加功能以同時關閉任何其他打開的帖子摘要。

我的問題的目的是理解ember如何在不犧牲隔離的情況下在組件之間說話。

我想到的解決方案是:

  1. 有一些包裝組件以某種方式處理它

  2. 觸發像'post-summery:open'這樣的事件並讓其他組件靠近它(但是然后它可以使用相同的組件與應用程序上的其他地方碰撞以進行不同的使用)

這是文檔中的原始演示: http//jsbin.com/uyibis/1/edit

這就是我用jQuery實現行為的方法: http//jsbin.com/eremon/2/edit

var $ contents = $('。content')。hide();

$(document).on('click','。title',function(){

$ contents.hide();
$(本)。接下來( '內容')顯示()。

});

在此輸入圖像描述

這個問題一直在Ember出現。 我解決它的方法是跟蹤控制器上哪個帖子“打開”,然后讓每個項目的視圖根據該數據負責自己的狀態。 這樣,每次切換時,您都不必手動重置每個帖子的狀態。

規范的真相來源是控制器。

App.IndexController = Ember.ArrayController.extend({
    content: null,
    selectedPost: null // null means no post selected
});

我們通過模板將這些信息連接到組件。

<script type="text/x-handlebars" data-template-name="index">
    {{#each post in controller}}
        {{post-summary post=post selectedPost=selectedPost}}
    {{/each}}
</script>

<script type="text/x-handlebars" id="components/post-summary">
    <h3 {{action "toggleBody"}}>{{post.title}}</h3>
    {{#if isShowingBody}}
        <p>{{{post.body}}}</p>
    {{/if}}
</script>

現在,可以通過屬性計算給定帖子的身體可見性。

App.PostSummaryComponent = Ember.Component.extend({
    post: null,
    selectedPost: null,

    isShowingBody: function() {
        return this.get('selectedPost') === this.get('post');
    }.property('selectedPost', 'post'),

    toggleBody: function() {
        this.set('selectedPost', 
                 this.get('isShowingBody') ? null : this.get('post'));
    }    
});

這是jsfiddle

有人可能會說這不是一個理想的面向對象的解決方案,但它已經徹底改善了我的Ember應用程序的結構和可維護性。 您可以通過讓每個元素基於共同的事實來源負責其自己的狀態來實現各種復雜的列表行為。

使用Ember.Component您無法控制childViews,因此我使用Ember.CollectionView來管理項目。 因為App.PostSummaryComponent已經擴展了Ember.Component ,所以我使用模板中的view containerViewClass委托給Ember.CollectionView這種行為。 所以我們擁有兩個世界中最好的一個。

由於該containerViewClass屬性是一個類,因此我們需要一種方法來在創建視圖時訪問該實例 - 與childViews進行交互。 為此,您必須在模板中使用viewName='containerView' 這告訴Ember,將在名為containerView的屬性中設置一個新的containerViewClass實例。 所以我們可以在App.PostSummaryComponent中使用App.PostSummaryComponent this.get("containerView")

最后一項更改是將each幫助程序從索引模板移動到組件模板。 所以其他人對該組件的調用不需要重復它。

http://jsbin.com/ebayip/2/edit

暫無
暫無

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

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