javascript - 在 Ember 中观察 ChildView 的正确方法?

标签 javascript model-view-controller ember.js javascript-framework

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

基本上,我有一个 Handlebars block View 作为父级,然后循环遍历项目数组并为每个项目创建子 block View 。后来,这些 child 以某种方式被修改,我想检测并处理该事件。

摘要代码:

{{#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)。当outerView最初被插入时,我们将突出显示应用于最后一个项目,并且它按预期工作。稍后,当我们添加新项目时,我们的突出显示方法会触发,但它看不到新项目。

关于此的 2 个问题:

  • 主要问题:为什么最后一项(Matt)没有突出显示?换句话说,为什么添加新项目后,childViews.length仍然报告旧值?有更好的方法吗?

  • 第二个问题:为什么当我们添加新项目时,childViews 上的观察者会触发两次? (总共 3 次:初始插入 1 次,添加 1 个新子项 2 次)

<小时/>

编辑:我稍微调整了 fiddle 以更好地说明我的需求。请注意外层 View (HTML + 内层 View )的混合内容。基本上,我的outerView需要接受任何内容作为子项,而不仅仅是 View /数据的数组/集合。

编辑 2:进一步说明:事后操作这些 subview 是另一回事,可以通过使用 childViews(ember View )的内容来完成或使用 jQuery 操作可能不是正式 ember View 对象的 HTML 元素,或任何其他方式。 这里的真正目标只是在任何外层 View 内容发生更改时捕获事件(使用 subview 的当前副本)。

编辑 3:这是一个 Issue on Github

最佳答案

你最初的代码看起来有点困惑。这是达到相同结果的更好方法:

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

您应该将每个项目包装在 Controller 中,这可以使用 {{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 类绑定(bind)到 Controller 的 active 属性:

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

关于javascript - 在 Ember 中观察 ChildView 的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15391898/

相关文章:

javascript - PHP生成的Js函数调用是用换行符创建的

java - 如何在多个类中使用 swing

objective-c - 将 NSPopupButton 绑定(bind)到 NSDictionaryController

javascript - 用于共享数据的 Ember 应用程序 Controller

ember.js - 每次我点击 Ember 应用程序中的链接时,关联的模型都会将相同的数据附加到页面

javascript - 如何在javascript函数onChange中传递两个参数

javascript - 如何从 Aurelia 中的函数更新属性

javascript - jQuery - "blind"中的选项 "setInterval"仍在运行

c# - 重定向到新选项卡中的页面时避免弹出窗口拦截器

javascript - 组件 Ember 的设置 Controller