【问题标题】:Observable array push multiple Objects in knockout.js可观察数组在 knockout.js 中推送多个对象
【发布时间】:2014-05-12 10:24:55
【问题描述】:

ko中是否有选项,可以同时推送多个元素?

我有两个元素需要插入到名为StatesList 的可观察数组中,我无法继续。我怎样才能同时添加它们。

见下文:

var model1 = jQuery.parseJSON(ko.toJSON(argsToPost));
var model = jQuery.parseJSON(ko.toJSON(self.StateModel));

我需要将两者都添加到我的ObservableArray

self.StatesList.push(model);
self.StatesList.push(model1);

这是插入不同的记录,我想同时插入两个对象

【问题讨论】:

  • 正如我在 cmets 中对我的回答所提到的,请尝试更清楚一点 - 您想要实现什么,以及您的代码的实际结果与您的预期有何不同? “同时”是什么意思?

标签: knockout.js


【解决方案1】:

我们确实有ko.utils.arrayPushAll(array, valuesToPush) 作为一个实用函数供您使用。 虽然它不能直接从 observableArrays 中获得

如果您添加您的pushAll to observableArrays,您可能希望对底层数组(在您的情况下为this())进行操作,然后在最后的observableArray 上调用valueHasMutated()。这将确保observableArray 的订阅者只收到一次最终结果通知,而不是每次推送。

在 KO 内核中,它也需要事先调用valueWillMutate()

关键是我不建议使用您发布的代码,因为它会在每次推送时通知,如果您推送许多项目,这可能会对性能产生影响。

在核心,我们可能会这样做:

ko.observableArray.fn.pushAll = function(valuesToPush) {
    var underlyingArray = this();
    this.valueWillMutate();
    ko.utils.arrayPushAll(underlyingArray, valuesToPush);
    this.valueHasMutated();
    return this;  //optional
};

John PapaRP Niemeyer 之间也发生了同样的讨论。可以找到链接here。因此,这里只发布有用的提示作为答案。

【讨论】:

  • 要明确一点,ko.utils.arrayPushAll() 只会循环遍历valuesToPush 并每次调用array.Push,这意味着它对于大型列表来说效率低下,并且默认情况下一次推送许多项目的目的。跨度>
  • @Slight 这个我在 Chrome 和 FF 上测试过的性能测试不同意jsperf.com/array-prototype-push-apply-vs-concat/76
  • @LostInComputer 您的测试涉及普通数组。我们谈论的是observableArray.Push,它会在每次调用时通知订阅者。您无需运行性能测试即可知道它比只通知一次要慢。
  • @Sligh 但是 RJK 答案中的代码不使用 observableArray.Push。它只使用底层(普通)数组。
  • @Slight 你是对的。对于 20,000 个项目,concat 在 IE11 和 Chrome 中更快。但是如果只有 20 个项目,循环会更快。 20 项:jsperf.com/array-prototype-push-apply-vs-concat/5
【解决方案2】:

试试

ko.utils.arrayPushAll(self.StatesList, [model, model1]);

【讨论】:

    【解决方案3】:

    pushAll 函数已在 github 上讨论,参见例如this issuethis pull request。据我所知,它还没有进入主代码。

    但是,您可以像这样轻松实现全推:

    var items = ko.observableArray();
    
    items.push.apply(items, [1, 2, 3, 4]);
    

    正如 stalniy 在第二个参考文献中所评论的那样。这样做的缺点是,淘汰赛会在推送每个项目后通知订阅者。

    或者,

    function concat(the_list, items_to_concat) {
        the_list.splice.apply(the_list, [the_list().length, 0].concat(items_to_concat));
    }
    

    因此使用了 observableArraysplice 实现,正如 brianmhunt 在同一线程上所建议的那样。

    顺便说一句:我承认我不知道这一点,我只是在谷歌上搜索了“push many knockout”

    【讨论】:

    • 您的建议可能可行,但不适用于我的情况!! ;)
    • @Aj_sari 很遗憾听到这个消息。我想我没有正确理解您的问题-我以为您正在寻求一种解决方案,以通过单个方法调用添加多个元素。您能否详细说明什么是“在您的情况下不起作用”?
    猜你喜欢
    • 2016-03-13
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2019-12-16
    • 2015-10-05
    • 1970-01-01
    • 2018-11-26
    • 2019-09-09
    相关资源
    最近更新 更多