[英]Backbone.js - Filter a Collection based on an Array containing multiple keywords
我正在使用Backbone.js/Underscore.js
來呈現一個HTML
表格,當您鍵入文本框時會對其進行過濾。 在這種情況下,它是一個基本的電話簿。
該表的內容來自一個由JSON文件填充的Collection。 下面是JSON文件的基本示例:
[{
"Name":"Sales and Services",
"Department":"Small Business",
"Extension":"45446",
},
{
"Name":"Technical Support",
"Department":"Small Business",
"Extension":"18800",
},
{
"Name":"Research and Development",
"Department":"Mid Market",
"Extension":"75752",
}]
我將文本框值轉換為小寫,然后將其值與Collection一起傳遞給此函數,然后將返回的值分配給新的Collection並使用它重新呈現頁面。
filterTable = function(collection, filterValue) {
var filteredCollection;
if (filterValue === "") {
return collection.toJSON();
}
return filteredCollection = collection.filter(function(data) {
return _.some(_.values(data.toJSON()), function(value) {
value = (!isNaN(value) ? value.toString() : value.toLowerCase());
return value.indexOf(filterValue) >= 0;
});
});
};
問題是函數是字面的。 要從我的示例中找到“銷售和服務”部門,我必須准確輸入,或者只是“銷售”或“服務”。 我無法輸入“sal serv”,仍然發現它是我想要做的。
我已經編寫了一些javascript,它似乎非常可靠地將文本分成一個單詞數組(現在更新為使用中的代碼)。
toWords = function(text) {
text = text.toLowerCase();
text = text.replace(/[^A-Za-z_0-9@.]/g, ' ');
text = text.replace(/[\s]+/g, ' ').replace(/\s\s*$/, '');
text = text.split(new RegExp("\\s+"));
var newsplit = [];
for (var index in text) {
if (text[index]) {
newsplit.push(text[index]);
};
};
text = newsplit;
return text;
};
我想循環遍歷“split”數組中的每個單詞,並檢查每個單詞是否存在於其中一個鍵/值中。 只要存在所有單詞,它就會傳遞真值迭代器並添加到Collection中並在表中呈現。
所以在我的例子中,如果我輸入“sal serv”,它會發現這兩個字符串都存在於第一個項目的Name中,並且會返回它。
但是,如果我鍵入“銷售業務”,則不會返回,因為盡管兩個值都出現在該項中,但“名稱”部分中不存在相同的兩個單詞。
我只是不確定如何在Backbone / Underscore中寫這個,或者即使這是最好的方法。 我查看了文檔並且不確定哪個函數最簡單。
我希望這是有道理的。 我對Javascript
有點新鮮,我意識到我已經潛入了深淵,但學習是有趣的部分;-)
如果需要,我可以提供更多代碼或JSFiddle。
使用下划線的any
和all
使這相對容易。 這是它的要點:
var toWords = function(text) {
//Do any fancy cleanup and split to words
//I'm just doing a simple split by spaces.
return text.toLowerCase().split(/\s+/);
};
var partialMatch = function(original, fragment) {
//get the words of each input string
var origWords = toWords(original + ""), //force to string
fragWords = toWords(fragment);
//if all words in the fragment match any of the original words,
//returns true, otherwise false
return _.all(fragWords, function(frag) {
return _.any(origWords, function(orig) {
return orig && orig.indexOf(frag) >= 0;
});
});
};
//here's your original filterTable function slightly simplified
var filterTable = function(collection, filterValue) {
if (filterValue === "") {
return collection.toJSON();
}
return collection.filter(function(data) {
return _.some(_.values(data.toJSON()), function(value) {
return partialMatch(value, filterValue);
});
});
};
注意:此方法計算效率非常低,因為它涉及首先循環集合中的所有項目,然后是每個項目的所有字段,然后是該項目值中的所有單詞。 此外,在循環內部聲明了一些嵌套函數,因此內存占用不是最佳的。 如果您有一小組數據,那應該沒問題,但如果需要,可以進行一些優化。 如果我有時間的話,我可能會稍后再回來編輯一下。
/代碼樣本未經測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.