2012-08-30 36 views
2

我有一個集合self.models。我還有一個對象數組,其中包含我希望應用到名爲filterArr的集合的字段和過濾器。這方面的一個例子是:下劃線 - 對值數組進行過濾

[{field: "Account", filter: "123"}, {field: "Owner", filter: "Bob"}] 

的問題是,我不知道我會如何挺我的每模型迭代只返回那些此filterArr也適用車型,我知道它有是這樣的事情,但這是硬編碼:

self.models = _.filter(self.models, function (model) { 
        model = model.toJSON(); 
        return model.Account === "123" && model.Owner === "Bob"; 

}); 
+0

我無法理解您所嘗試的內容。 – fguillen

回答

-2

基本上你需要迭代模型的屬性和它們的鍵和值與過濾器的屬性。

self.models = _.filter(self.models, function (model) { 
    var fits = true; // does this model "fit" the filter? 
    model = model.toJSON(); 
    _.each(model, function(modelVal, modelKey) { 
    _.each(filterArr, function(filter) { 
     if (modelKey === filter.field && modelVal !== filter.filter) { 
      fits = false 
     } 
    } 
    }) 
    return fits 
}) 

但是,有一點點的下劃線魔法有一個棘手的方法。我不確定它在性能方面是否更好,但它肯定會讓我看起來更好。

// change a bit the way filter is described: 
var filter = {Account: '123', Owner: 'Bob'}, 
    // save an array of filter keys (Account, Owner) 
    filterKeys = _.keys(filter), 
    // and an array of its values (123, Bob) 
    filterVals = _.values(filter) 
self.models = _.filter(self.models, function (model) { 
     // pick a subset of model which has the same keys as filter 
    var filteredSubset = _.pick(model.attributes, filterKeys), 
     // pick values of this subset 
     subsetValues = _.values(filteredSubset) 
     // this values have to be equal to filter's values 
     // (use .join() to turn array to string before comparison due to references) 
     return filteredVals.join() === subsetValues.join() 
}) 

請注意,在後一種情況下,所有模型必須具有在過濾器中聲明的所有鍵。

如果我是你,我正在尋找一個最可靠的方法,我會重寫第一個例子,但會改變_.each標準for循環,一旦第一個「無匹配」值滿足返回false

+0

非常好!到底是什麼我! – CallumVass

+0

很高興幫助,但要確保你考慮到jakee的答案:它的所有要點都完全有效 –

7

首先,下劃線的過濾器返回Array,所以你在這裏有效地做的是用一個過濾數組替換你的集合。這樣的事情會更合適:

this.filtered = _.filter(this.models, ...); 

骨幹系列採用了最underscore's useful functions。所以,上面的解決方案是遠遠沒有達到最佳,而不是做這樣的事情(其實它並沒有在所有你想要的方式工作):

this.filtered = this.models.filter(function() {...}); 

最好的方式來獲得和名稱設置模型字段到目前爲止,Backbone Modelgetsetfunctions,所以爲什麼不使用它們? Model.toJSON()的作品,但你只是複製attributes -hash不必要的周圍。

this.filterObj = { // Why not make it an object instead of array of objects 
    "Account": "123", 
    "Owner": "Bob" 
}; 
this.filtered = this.models.filter(function(model) { 
    // use the for in construct to loop the object 
    for (filter in filterObj) { 
    // if the model doesn't pass a filter check, then return false 
    if (model.get(filter) !== filterObj[filter]) return false; 
    } 
    // the model passed all checks, return true 
    return true; 
}); 

希望這會有所幫助!