2014-03-03 24 views
4

我有computed,它基於observableArray屬性headers。另外我有用於添加和刪除多個headers方法:如何在執行多個陣列推/取操作時計算暫時停止計算

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

當我打電話addHeadersremoveHeadersnewHeaders呼籲在headers陣列的每個項目。有什麼解決方案如何暫停計算計算場? (有些像用戶ko.valueWillMutate,ko.valueHasMutated)。

回答

3

Knockout.js Performance Gotcha #2 - Manipulating observableArrays

更好的圖案是讓我們底層數組的引用,推 它,然後調用.valueHasMutated()。現在,我們的用戶將只有 收到一個通知,指示陣列已更改。

我分叉瑞恩·尼邁耶的jsfiddle例如here ..打開控制檯,並檢查消息'calling computed object'多少次登錄!

+0

謝謝,這個解決方案正是我需要的。 – alexmac

+0

或者使用'push.apply' ...'this.children.push.apply(this.children,newChildren);'...哦,那個頁面確實提到了這個。 – MrYellow

1

請記住,可觀察數組仍然只是一個可觀察對象。你可以得到數組的值var arr = oarr(),做任何你想做的事情,然後把它放回oarr(arr)

+0

性能如何呢?我認爲將一個修改過的數組賦給'observableArray'屬性不會提高性能。你怎麼看? – alexmac

+0

它的確如此。在您的示例中,每次推送時都會重新計算該值。如果你提取它,使用普通的JavaScript推送,並重新分配,該值將被重新計算一次。 – sabof

+0

我正在努力提高性能,減少調用計算函數。我擔心爲'observableArray'分配一個修改後的值會比其他調用函數更慢。 – alexmac

1

Knockout 3.1.0包含rateLimit extender,可以快速方便地提高此場景中的性能。只需將擴展應用到您觀察到的數組:

self.headers = ko.observableArray().extend({rateLimit: 0}); 

(版本3.1.0是目前[2014年3月3日]可作爲一個測試版。)

如果你只在延遲感興趣計算可觀察(而不是依賴於數組的所有內容),則可以將rateLimit擴展器應用於計算的observable。如果您使用淘汰賽3.0或更早版本,則可以使用在該throttle擴展計算來實現類似的結果:

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

不幸的是我使用v3.0( – alexmac

+0

)在3.0中,如果你想要延遲的話,你可以在計算的observable上使用'throttle'擴展器(雖然'throttle'在可觀察數組上不起作用) –

+0

Yes,i知道'throttle',但是有底層陣列的解決方案,對我來說更好。 – alexmac