ember.js | 在一个组件操作上通知其他组件

Asa*_*atz 4 ember.js

Ember的指南组件部分有一个Post Summary Component的演示,点击一个Post Summery标题打开它下面的内容.

我想添加功能以同时关闭任何其他打开的帖子摘要.

我的问题的目的是理解ember如何在不牺牲隔离的情况下在组件之间说话.

我想到的解决方案是:

  1. 有一些包装组件以某种方式处理它

  2. 触发像'post-summery:open'这样的事件并让其他组件靠近它(但是它可以使用相同的组件与app上的其他地方碰撞以进行不同的使用)

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

这就是我用jQuery实现行为的方法:http: //jsbin.com/eremon/2/edit

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

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

$ contents.hide();
$(本).接下来( '内容')显示().

});

在此输入图像描述

ahm*_*eod 5

这个问题一直在Ember出现.我解决它的方法是跟踪控制器上哪个帖子"打开",然后让每个项目的视图根据该数据负责自己的状态.这样,每次切换时,您都不必手动重置每个帖子的状态.

规范的真相来源是控制器.

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

我们通过模板将这些信息连接到组件.

<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>
Run Code Online (Sandbox Code Playgroud)

现在,可以通过属性计算给定帖子的身体可见性.

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'));
    }    
});
Run Code Online (Sandbox Code Playgroud)

这是jsfiddle.

有人可能会说这不是一个理想的面向对象的解决方案,但它已经彻底改善了我的Ember应用程序的结构和可维护性.您可以通过让每个元素基于共同的事实来源负责其自己的状态来实现各种复杂的列表行为.