在下面的示例中,您将看到doSomething永远不会触发。如果从模板绑定中删除if: Comments
,则会按预期触发。有谁知道导致这种情况发生了什么?在模板绑定处理程序上使用data
属性时也会发生这种情况。
我目前正在使用Knockout 2.2.1。 jsfiddle http://jsfiddle.net/YADzx/2/
<div data-bind="template: { if: Comments, name: 'comments' }"></div>
<script type="tmpl" id="comments">
<div data-bind="foreach: { data: Comments, afterAdd: $root.doSomething }">
<div data-bind="text: name"></div>
</div>
</script>
<script>
var vm = {
Comments: ko.observableArray([{name:'hey'}]),
doSomething: function (element, index, data) {
$(element).addClass('wow');
}
};
ko.applyBindings(vm);
vm.Comments.push({name:'foo'});
vm.Comments.push({name:'bar'});
</script>
答案 0 :(得分:10)
if
绑定上的template
条件会导致Comments
更改时更新。然后Knockout将重新呈现整个模板,并且foreach
绑定的先前状态将丢失。
根据您想要或不想要的副作用,有几种方法可以解决这个问题。
删除if
选项。您的代码仍然可以使用,但您的HTML中会<div>
绑定foreach
。因此,如果弄乱你的布局,这不是一个好的选择。
从if
拆分template
,并使用if
绑定使用其他元素(或注释语法)。只要您使用的是Knockout 2.2.0或更高版本,这将有效。
<script type="tmpl" id="comments">
<!--ko if: Comments-->
<div data-bind="foreach: { data: Comments, afterAdd: $root.doSomething }">
<div data-bind="text: name"></div>
</div>
<!--/ko-->
</script>
使用if
绑定代替使用visible
绑定,该绑定会隐藏当前元素并且不会重新呈现。
<script type="tmpl" id="comments">
<div data-bind="visible: Comments, foreach: { data: Comments, afterAdd: $root.doSomething }">
<div data-bind="text: name"></div>
</div>
</script>
但要考虑的一件事是,observableArray
通常不会包含假值。那是因为在JavaScript中,空数组仍然是真的。如果您要测试空数组,则需要从if: Comments
更改为if: Comments().length
。