0

在下面的示例中,您将看到 doSomething 永远不会触发。如果您if: Comments从模板绑定中删除 doSomething ,则会按预期触发。有谁知道这是怎么回事?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>
4

1 回答 1

10

绑定的if条件template会导致它在更改时更新Comments。然后,Knockout 将重新渲染整个模板,并且之前的foreach绑定状态会丢失。

根据您想要或不想要的副作用,有几种方法可以解决此问题。

  1. 删除该if选项。您的代码仍然可以工作,但您将在 HTML 中<div>使用foreach绑定。因此,如果它弄乱了您的布局,这不是一个好的选择。

  2. 拆分iffromtemplate并使用if绑定的另一个元素(或注释语法)。只要您使用的是 2.2.0 或更高版本的 Knockout,这将起作用。

    <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>
    
  3. 不要使用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: Commentsif: Comments().length

于 2013-04-05T02:04:57.817 回答