这是fiddle for this question(确保已打开控制台):

基本上,我有一个作为父项的车把块视图,然后遍历项目数组并为每个项目创建子块视图。后来,以某种方式修改了这些孩子,我想检测并处理该事件。

摘要代码:

{{#view App.outerView}}
    {{#each item in items}}
        <h6>Person:</h6>
        {{#view App.innerView}}
            <dl>
                <dt>First Name</dt><dd>{{item.first}}</dd>
                <dt>Last Name</dt><dd>{{item.last}}</dd>
            </dl>
        {{/view}}
    {{/each}}
{{/view}}


稍后:

controller.get( 'items' ).pushObject( 'new item' );


在jsFiddle中,我试图使最后一个子对象始终突出显示(active = true)。最初插入externalView时,我们将突出显示应用于最后一项,并且按预期方式工作。稍后,当我们添加新项目时,我们的亮点方法将触发,但是看不到新项目。

关于此的2个问题:


主要问题:为什么最后一项(Matt)没有突出显示?换句话说,为什么在添加新项目后childViews.length仍报告旧值?有没有更好的方法可以做到这一点?
次要问题:为什么添加新项目时childViews上的观察者会触发两次? (共3次:初次插入1次,从添加1个新子项开始2次)




编辑:我已经调整了小提琴,以更好地说明我的需求。请注意externalView(HTML + innerViews)的混合内容。基本上,我的externalView需要接受任何内容作为子元素,而不仅仅是视图/数据的数组/集合。

编辑2:进一步说明:在事实不同之后处理这些子视图,可以通过使用childViews的内容(ember视图)或使用jQuery操纵可能不是正式余烬视图的HTML元素来实现。对象或其他任何方式。此处的真正目标只是在任何externalView内容发生更改时捕获事件(使用childViews的当前副本)。

编辑3:这是一个Issue on Github

最佳答案

您的初始代码看起来有些混乱。这是达到相同结果的更好方法:

http://jsfiddle.net/XaN8T/1/

您应该将每个项目包装在控制器中,这可以通过{{each}}帮助器轻松完成:

<script data-template-name="application" type="text/x-handlebars">
    This is a list:
    <ul>
        {{each controller itemController="item" itemViewClass="App.ItemView"}}
    </ul>
</script>


并为您的商品创建一个单独的模板:

<script data-template-name="item" type="text/x-handlebars">
    <h6>Person:</h6>
    <div {{bindAttr class=":content active"}}>
        <dl>
            <dt>First Name</dt><dd>{{first}}</dd>
            <dt>Last Name</dt><dd>{{last}}</dd>
        </dl>
    </div>
</script>


然后,可以使用needs属性利用Ember中的active和计算属性:

App.ItemController = Ember.ObjectController.extend({
    needs: ['application'], //This way each ItemController can access the ApplicationController's content (i.e. the list of all items)
    active: function() {
        return this.get('controllers.application.lastObject') === this.get('content');
    }.property('controllers.application.lastObject')
});


然后App.ItemView将其css类绑定到控制器的active属性:

App.ItemView = Ember.View.extend({
    tagName: 'li',
    templateName: 'item',
    classNameBindings: ['controller.active']
});


瞧!有用 :)

10-06 00:10