依赖可观察量中的大型数组 – 级联

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

我使用了许多包含级联逻辑的多选下拉列表。 我有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); 

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

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

所以我的问题归结为:

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

非常感谢您的帮助

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

 function registerDependency(observable) { if (ko.utils.arrayIndexOf(dependencies, observable)) { dependencies.push(observable); } } 

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

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

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

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

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

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

Interesting Posts