Knockout afterRender 只触发一次

Posted

技术标签:

【中文标题】Knockout afterRender 只触发一次【英文标题】:Knockout afterRender fires only once 【发布时间】:2017-07-11 19:37:47 【问题描述】:

我有这个简单的 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

【问题讨论】:

【参考方案1】:

问题出在你的

foreach: arr, afterRender: initPlugins($data)

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

foreach: arr, afterRender: initPlugins 

afterRender 方法将通过 2 个参数被敲除调用:

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

【讨论】:

谢谢,它有效!有什么干净的方法可以访问 afterRender 中的 ViewModel 吗?

以上是关于Knockout afterRender 只触发一次的主要内容,如果未能解决你的问题,请参考以下文章

knockout.js完成呈现所有元素后成功回调

knockout.js 完成渲染所有元素后的成功回调

extjs 组合框 afterrender() 一起调用导致异步 ajax 调用

Knockout JS 防止在特定子节点上触发点击事件

Knockout/Select2:触发 select2 根据可观察的选项更新进行更新

Knockout.js:当可观察数组中的值发生变化时触发计算的最佳方法是啥