这是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)。最初插入outerView时,我们将突出显示应用于最后一项,它按预期工作。稍后,当我们添加一个新项目时,我们的突出显示方法会触发,但它不会看到新项目。
关于这个的2个问题:
主要问题:为什么最后一项(Matt)没有突出显示?换句话说,为什么在添加新项目之后,childViews.length
是否仍会报告旧值?有没有更好的方法来做这件事?
次要问题:为什么childViews
上的观察者在我们添加新项目时会两次开火? (总共3次:初始插入时为1,添加1个新子项目时为2)
编辑:我已经调整了一点小提琴以更好地说明我的需求。注意outerView(HTML + innerViews)的混合内容。基本上,我的outerView需要接受任何内容作为子项,而不仅仅是视图/数据的数组/集合。
编辑2 :进一步澄清:在事实之后操纵这些子视图是一个不同的故事,可以通过使用childViews
(ember视图)的内容或使用jQuery来完成操纵可能不是正式的余烬视图对象的HTML元素,或任何其他方法。 这里的真正目标是在任何outerView内容发生更改时(使用当前的childViews副本)捕获事件。
编辑3 :这是Issue on Github
答案 0 :(得分: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
和active
属性在Ember中计算属性:
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']
});
瞧!它有效:)
答案 1 :(得分:0)
然后添加一个计算属性,用于确定itemViewClass
类的active
上孩子是否是最后一个
active: function () {
return this.get("elementId") === this.get("parentView.childViews.lastObject.elementId");
}.property('parentView.childViews.length'),
注意每当需要处理视图集合时,请使用CollectionView
或Ember.ContainerView(这样可以更好地控制子视图操作)要求,但对于大多数情况Ember.CollectionView
就足够了