2013-02-03 34 views
0

我有一個用戶可以執行搜索的對象數組。我使用基於搜索的ko.computed函數來創建另一個匹配項目數組以供顯示。knockout.js計算函數來創建兩個數組?

self.matchedRecords = ko.computed(function() { 
    return ko.utils.arrayFilter(self.transponders(), function(r) { 
    return r.title.toLowerCase().indexOf($('.search-input').val().toLowerCase()) > -1 
    } 
}; 

這很好,我對目前的表現印象深刻。

這個問題是我也需要「不匹配」的記錄,因爲我在某些情況下(60%的時間)必須對它們執行一個加法操作。我真的不想創建第二個ko.computed函數,因爲每次執行搜索時都必須再次運行該數組。

所以,我的問題:有沒有一種方法可以使用相同的ko.computed創建第二個不匹配的項目數組?基本上通過陣列,並把每個項目在匹配或不匹配的陣列...

如果不是,它是更快: 1)創建第二個ko.computed獲取我的數組中的不匹配項作爲用戶搜索;或 2)寫一個arrayDiff函數,並根據需要確定不匹配的項目,如果我需要它們。

乾杯!

+0

只是用計算出的第二,你都落入過早優化 –

回答

1

如果您擔心性能問題,則可以在迭代計算結果中的搜索結果時填充不可觀察的數組。另外請注意,您在循環中反覆選擇使用jQuery,我認爲這會抵消任何KO導致的減速。

self.missedRecords = []; 

self.matchedRecords = ko.computed(function() { 
    var searchQuery = $('.search-input').val().toLowerCase(), 
     transponders = self.transponders(), 
     matched = []; 

    // Clear out missed records 
    self.missedRecords.length = 0; 

    _.each(transponders, function(transponder) { 
     if (transponder.title.toLowerCase().indexOf(searchQuery) >= 0) { 
      matched.push(transponder); 
     } else { 
      self.missedRecords.push(transponder); 
     } 
    }); 

    return matched; 
}); 

我使用了Underscore的_.each來縮短代碼。此方法的缺點是對missedRecords的更改無法(可靠地)綁定到UI(例如,如果您有綁定foreach)。

如果您確實需要missedRecords陣列可觀察到,仍然希望保持快速(ER),你可以做這樣的事情:

self.missedRecords = ko.observableArray([]); 

self.matchedRecords = ko.computed(function() { 
    var searchQuery = $('.search-input').val().toLowerCase(), 
     transponders = self.transponders(), 
     matched = [], 
     missed = []; 

    _.each(transponders, function(transponder) { 
     if (transponder.title.toLowerCase().indexOf(searchQuery) >= 0) { 
      matched.push(transponder); 
     } else { 
      missed.push(transponder); 
     } 
    }); 

    // Clear out missed records, without triggering subscriptions 
    self.missedRecords().length = 0; 

    // Copy the local missed array to the KO observable array 
    // This will NOT trigger notifications 
    ko.utils.arrayPushAll(self.missedRecords(), missed); 

    // Tell KO that the observable array has mutated - this will trigger changes 
    // to anything observing the missedRecords array 
    self.missedRecords.valueHasMutated(); 

    return matched; 
}); 

你也可以跳過computed乾脆只訂閱更改以更改陣列的狀態。例如:

self.missedRecords = ko.observableArray([]); 
self.matchedRecords = ko.observableArray([]); 

self.transponders.subscribe(function(newTransponders) { 
    var matched = [], 
     missed = []; 

    _.each(newTransponders, function(transponder) { 
     // Populate matched/missed local arrays 
    }); 

    // Copy the arrays to the observableArray instances using the technique above 
}); 
+0

我覺得你與訂閱擁有它..從來沒想過做這樣的 - 謝謝! – whiteatom