Javascript 如何在执行多个数组推/删除操作时临时停止计算

Javascript 如何在执行多个数组推/删除操作时临时停止计算,javascript,knockout.js,Javascript,Knockout.js,我已根据可观察到的array属性标题计算了。此外,我还有添加和删除多个标题的方法: function ViewModel() { var self = this; self.headers = ko.observableArray(); self.newHeaders = ko.computed(function() { var countOfNew = 0; ko.arrayForEach(self.headers(), functio

我已根据
可观察到的array
属性
标题
计算了
。此外,我还有添加和删除多个
标题的方法:

function ViewModel() {
    var self = this;

    self.headers = ko.observableArray();
    self.newHeaders = ko.computed(function() {
        var countOfNew = 0;
        ko.arrayForEach(self.headers(), function(header) {
            if (!header.id) {
                countOfNew++;
            }
        });
        return countOfNew;
    });

    self.addHeaders = function(headers) {
        ko.arrayForEach(headers, function(header) { 
            self.headers.push(header);
        }
    };

    self.removeHeaders = function(headers) {
        ko.arrayForEach(headers, function(header) { 
            self.headers.remove(header);
        }
    };
}

当我调用
addHeaders
removeHeaders
时,
newHeaders
headers
数组中的每个项目调用。有什么办法可以暂时停止计算计算字段吗?(例如
ko.valueWillMutate
ko.valuehassmutated
,用于订阅者)。

请记住,可观察数组仍然只是可观察数组。您可以获取数组的值
var arr=oarr()
,对其执行任何操作,然后将其放回

更好的模式是获取对底层数组push的引用 然后调用.valueHasMutated()。现在,我们的订户只会 接收一个指示阵列已更改的通知


我给出了Ryan Niemeyerjshiddle示例。。打开控制台并检查消息
“调用计算对象”
记录了多少次

Knockout 3.1.0包括可以快速轻松地提高此场景中性能的。只需将扩展器应用于可观察阵列:

self.headers = ko.observableArray().extend({rateLimit: 0});
(3.1.0版目前是[3/3/2014]的测试版。)

如果您只想延迟计算的可观测数据(而不是依赖于数组的所有数据),则可以将
rateLimit
extender应用于计算的可观测数据。如果您使用的是Knockout 3.0或更早版本,您可以在计算机上使用
油门
扩展器来获得类似的结果:

self.newHeaders = ko.computed(function() {
    ...
}).extend({throttle: 1});

性能如何?我认为将修改后的数组分配到
observableArray
属性不会提高性能。你觉得呢?是的。在您的示例中,每次推送时都会重新计算该值。如果您提取它,使用普通的JavaScript推送,然后重新分配,该值将只重新计算一次。我担心将修改后的值分配给
observableArray
会比额外调用computed函数慢得多。计算的实现方式是,每当修改数组时都会调用它,并且总是遍历所有项。你为什么说它会慢一些?我有大约200个标题,当我将修改后的数组分配给
observearray
时,knockout将在视图中呈现所有标题。此操作的时间大于计算的时间。谢谢,此解决方案正是我需要的。或者使用
push.apply
<代码>this.children.push.apply(this.children,newChildren)。。。哦,该页面确实提到了这一点。不幸的是,我使用的是v3.0(在3.0中,如果您只想延迟,您可以在计算的可观察对象上使用
throttle
扩展器(
throttle
在可观察数组上不起作用)是的,我知道throttle
,但是底层数组的解决方案对我来说更合适。Michael,我从这里借用了Ryan Niemeyer的JSFIDLE,似乎“add new bad”按钮在我添加之后只重新评估了一次。extend({Rate Limit:0})到items observable数组。如果使用rateLimit,现在可以推到observable数组吗?@sfor是的,可以。在3.4.0中,您也可以使用
extend({deferred:true})
而不是
rateLimit