Knockout afterRender 仅触发一次

Knockout afterRender fires only once

我有这个简单的 ViewModel:

 export class ViewModel {
    public arr : KnockoutObservableArray<Dtos>;
    constructor() {
        this.arr = ko.observableArray<Dtos>(null);
        ko.applyBindings(this);
        this.init();
    }

    private init() {
        var self = this;
        ajaxCall().done(item => {
                self.arr(item.Dtos);                   
            });
    }

    public initPlugins() {
         jQuery(".external-events > li")
            .each(function() {
                if ($(this).attr("event-draggable") == "false")
                    return true;
                jQuery(this).draggable({
                zIndex: 999,
                revert: true, // will cause the event to go back to its
                revertDuration: 0 // original position after the drag
            });
         });
    }
}

此虚拟机正在应用于此标记:

<ul class="external-events" data-bind="foreach: {arr, afterRender: initPlugins($data)}">
    <li event-draggable="false">
        <div class="bg-info">
            <span data-bind="text: Name"></span>
        </div>
        <ul  class="external-events" data-bind="foreach: moreStuff">
            <li>
                <div class="bg-info">
                    <span data-bind="text: Name"></span>
                </div>
            </li>
        </ul>
    </li>
</ul>

问题是 foreach 绑定的 afterRender 事件只被触发一次,显然是在 ko.applyBindings 之后,但 DOM 还没有准备好,所以我们无法初始化 jQuery.ui 可拖动对象。

根据 Ko 文档,afterRender 应该在每次 observableArray(属于相应的 foreach)发生变化时触发,但它没有发生。

最终我在填充数组后通过初始化 ajax.done 中的可拖动对象使其工作,但我觉得这不是正确的方法,但问题仍然存在,afterRender 数组更新时未触发。

如有任何想法,我们将不胜感激。

PS:按数组我显然是指ko.observableArray

问题出在你的

foreach: {arr, afterRender: initPlugins($data)}

afterRender 需要一个函数作为参数,但是你通过调用它以数据作为参数来调用函数,将其更改为:

foreach: {arr, afterRender: initPlugins }

afterRender 方法将被 knockout 使用 2 个参数调用:

插入的 DOM 个元素的数组,它们所绑定的数据项