依赖观察值中的大型数组 - 级联

Cra*_*uce 3 javascript algorithm jquery knockout.js

我正在使用Knockout JS,因为业务需求要求大多数(如果不是全部)逻辑由于低带宽用户而在浏览器中处理.到目前为止,除了一个问题外,它的功能还很棒.

我使用了许多包含级联逻辑的多选下拉列表.我有8个列表处理分层数据并更改子列表中的可选选项.

这一切都很好,直到我到达底部的2个列表,这些列表可能包含3000个项目,具体取决于父列表选择(特别是当单击"全选"时).

问题是,在IE中,我得到了很长时间运行脚本警告消息,我需要摆脱它.这是一些代码:

viewModel.BottomLevelList= ko.dependentObservable(function () {
        if (this.ParentList().length === 0) { //nothing selected
            return [];
        }          
        var result = [];
        var i = self.longMasterList.length;
        var currentId = 0;
        while (i--) {
           //psuodo code:
           //this.ParentList().Contains(loop-item) then
               //put in return list based on some further logic
           //else continue
        }

        return result;


    }, viewModel);
Run Code Online (Sandbox Code Playgroud)

我尝试使用SO中的各种setTimeout技术来打破大型阵列并将控制暂时返回到浏览器,但没有成功.结果永远不会返回和/或observable似乎分离自己在UI中留下一个空列表.

如果我需要使用AJAX,我会,但这是最后的手段,并希望将其保留在客户端.

所以我的问题归结为:

  • 如何处理大型数据集(在Knockout JS依赖的observables和级联列表的上下文中),我如何停止长时间运行的脚本警告
  • 在这种情况下,我是否可以/应该使用一些惯用的JavaScript技术
  • 我在这里看不到树木了吗?!

非常感谢您的帮助

小智 6

我会先建议你优化你的dependentObservable.当您读取任何observable时,Knockout会在Dependency Manager中向它注册一个依赖项.它包含非常简单的代码,如下所示:

function registerDependency(observable) {
    if (ko.utils.arrayIndexOf(dependencies, observable)) {
        dependencies.push(observable);
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以在你的伪代码中看到你正在while循环中访问this.ParentList().这意味着registerDependency将被调用3000次并且dependencies阵列将被扫描3000次,这对IE来说是不好的(因为它没有内置的Array.indexOf方法).

所以我的头号建议是:在循环之前读取所有可观察量.

如果它没有帮助,我建议你继续使用setTimeout().这有点棘手.请查看此示例:http://jsfiddle.net/romanych/4KGAv/3/

我已经定义了asyncObservable.您应该传递一个包含dependentObservable的所有依赖项的数组.当ko.toJS被调用时,所有可观察者都被打开.然后我们使用dependencies数组中枚举的参数调用传递的回调函数.此函数将被评估为异步.

我已将此代码包装到ko.dependentObservable中,以便loader在传入的传递元素的任何更改时重新评估回调dependencies

更新:我的代码在这个问题上过于复杂.节流扩展器将成功.请查看此示例:http://jsfiddle.net/romanych/JNwhb/1/