Performance Knockout提示用于一次更新大量可观察量

时间:2013-06-19 16:46:24

标签: knockout.js

我正在使用这个计算,并且你可以想象,当我点击selectAll时,所有复选框都被选中(逐个)并且我'认为'可以是优化的所以所有得到检查然后重新评估模型,但我不确定它是否可能。

self.selectAllExpired = ko.computed({
                    read: function() {
                        return ko.utils.arrayFirst(self.paymentOrdersExpired(), function(order) {
                            return !order.isSelected();
                        }) == null;
                    },
                    write: function(value) {
                        ko.utils.arrayForEach(self.paymentOrdersExpired(), function(order) {
                            order.isSelected(value);
                        });
                    },
                    owner:this
                });

2 个答案:

答案 0 :(得分:1)

对于这种情况,节流是一个不错的选择:http://knockoutjs.com/documentation/throttle-extender.html

即使使用.extend({ throttle: 1 })添加到计算中,也会阻止计算在检查每个框时触发多次更新。

答案 1 :(得分:0)

这是我用来避免在项目选择发生变化时重新检查整个数组的算法:

function getIsAllSelectedComputed(arrayObservable) {
    var unSelectedCount = ko.observable(), arrayVersion = 0;
    function updateSelectedCheck(arrayValue) {
        ++arrayVersion; // Whenever the array changes, increment the version
        var initialUnSelectedCount = 0;
        ko.utils.arrayForEach(arrayValue, function(item) {
            var previousValue = item.isSelected();
            if (!previousValue)
                initialUnSelectedCount++;
            if (!item._isSelectedSubVersion) {
                item.isSelected.subscribe(function(latestValue) {
                    if (item._isSelectedSubVersion === arrayVersion) {
                        // Only update the unSelectedCount if the "truthiness" has changed
                        if (Boolean(previousValue) ^ Boolean(latestValue))
                            unSelectedCount(unSelectedCount() + (latestValue ? -1 : 1));
                        previousValue = latestValue;
                    }
                });
            }
            item._isSelectedSubVersion = arrayVersion;
        });
        unSelectedCount(initialUnSelectedCount);
    }
    updateSelectedCheck(arrayObservable());
    arrayObservable.subscribe(updateSelectedCheck);

    return ko.computed({
        read: function() {
            return (unSelectedCount() === 0);
        },
        write: function(value) {
            ko.utils.arrayForEach(arrayObservable(), function(item) {
                item.isSelected(value);
            });
        }
    });    
}

示例:http://jsfiddle.net/mbest/ssEqj/