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

发布于 2024-12-29 18:37:44 字数 1155 浏览 0 评论 0原文

我正在使用 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);

我尝试使用 SO 中的各种 setTimeout 技术来分解大数组并将控制权暂时返回给浏览器,但没有成功。结果永远不会返回和/或可观察对象似乎自行分离,在 UI 中留下一个空列表。

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

所以我的问题归结为:

  • 如何停止由于处理大型数据集而导致长时间运行的脚本警告(在 Knockout JS 依赖的可观察值和级联列表的上下文中)
  • 是否有一些惯用的 JavaScript 技术我可以/应该在此使用场景
  • 我是不是只见树木不见森林?!

非常感谢您的帮助

I am using Knockout JS, as business requirements dictate that most, if not all logic is processed in the browser due to low bandwidth users. It's working out awesome so far except for one issue.

I am using a number of multiselect dropdown lists that all contain cascading logic. I have, say 8 lists that process hierarchical data and alter selectable options in child lists.

This is all good until I get to the bottom 2 lists which could potentially contain 3000 items depending on parent list selections (especially when 'select all' is clicked).

the problem is, in IE, I'm getting long running script warning messages, which I need to get rid of. Here's some code:

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);

I have tried using various setTimeout techniques from SO to break the large array up and return control momentarily to the browser, but with no success. The result is never returned and / or the observable seems to detach itself leaving an empty list in the UI.

If I need to use AJAX I will, but this is a very last resort and would prefer to keep it in the client.

So my question boils down to:

  • How can I stop long running script warnings as a result of processing large data sets (in the context of Knockout JS dependant observables and cascading lists)
  • Is there some idiomatic JavaScript technique I could / should be using in this scenario
  • Am I not seeing the wood for the trees here?!

Thanks muchly for any help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑咖 2025-01-05 18:37:44

我首先建议您优化您的dependentObservable
当您读取任何可观察量时,Knockout 会在依赖项管理器中注册对其的依赖项。它包含非常简单的代码,如下所示:

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 时,所有可观察对象都会被解包。然后,我们使用 dependency 数组中枚举的参数来调用传递的回调函数。该函数将被异步评估。

中传递的传递元素的任何更改的回调

我已将此代码包装到 ko.dependentObservable 中,以重新评估 loaderdependency UPDATE
对于这个问题,我的代码过于复杂。 节流扩展器就可以了。请查看此示例:http://jsfiddle.net/romanych/JNwhb/1/

I would first suggest that you optimize your dependentObservable.
When you read any observable, Knockout registers a dependency to it in Dependency Manager. It contains pretty simple code like this:

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

I can see in your pseudo-code that you are accessing this.ParentList() in the while loop. It means registerDependency will be called 3000 times and the dependencies array will be scanned 3000 times, which is bad for IE (since it has no built-in Array.indexOf method).

So my number one suggestion would be: Read all observables before loops.

If it doesn't help, I suggest that you proceed with setTimeout(). It is a bit tricky. Please check out this example: http://jsfiddle.net/romanych/4KGAv/3/

I have defined asyncObservable. You should pass an array with all dependencies of your dependentObservable. When ko.toJS is called, all observables are unwrapped. Then we call the passed callback function with arguments enumerated in the dependencies array. This function will be evaluated async.

I have wrapped this code into ko.dependentObservable to re-evaluate loader callback on any change of passed elements passed in dependencies

UPDATE:
My code was overcomplicated for this issue. throttle extender will do the trick. Please checkout this sample: http://jsfiddle.net/romanych/JNwhb/1/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文