依赖可观察量中的大型数组 – 级联
我正在使用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/