我正在使用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,将文本划分为一个Word数组(现在更新为使用中的代码)似乎非常可靠。
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。
答案 0 :(得分:1)
使用下划线的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);
});
});
};
注意:此方法计算效率非常低,因为它首先循环遍历集合中的所有项目,然后是每个项目的所有字段,然后是该项目值中的所有单词。此外,在循环内部声明了一些嵌套函数,因此内存占用不是最佳的。如果您有一小组数据,那应该没问题,但如果需要,可以进行一些优化。如果我有时间的话,我可能会稍后再回来编辑一下。
/未经测试的代码示例