Как написать фильтр углов для поиска струнных фрагментов/последовательностей строк
Я пытаюсь написать собственный фильтр angularjs, который проверяет, содержит ли массив стран строку поиска, введенную пользователем.
Строка может состоять из одной буквы (например, "E" ) или фрагмента n-букв (например, "lan" ) или целого слова (например, "Англия" ).
В каждом случае все страны, содержащие эту одну букву или этот фрагмент, должны быть возвращены, поэтому "E" вернет "Англию", "Эстония" и т.д., в то время как "lan" вернет "Англию", "Ирландию" и т.д..
Пока мой фильтр возвращает всю страну или отдельные буквы, но у меня возникают трудности со строковыми фрагментами:
-
Шаблон HTML:
<input ng-model="filter.text" type="search" placeholder="Filter..."/>
<ul>
<li ng-repeat="item in data | listfilter:filter.text">
</ul>
-
angularJS
angular.module('sgComponents').filter('listfilter',[ function () {
return function(items, searchText) {
var filtered = [];
angular.forEach(items, function(item) {
if(item.label === searchText) { // matches whole word, e.g. 'England'
filtered.push(item);
}
var letters = item.label.split('');
_.each(letters, function(letter) {
if (letter === searchText) { // matches single letter, e.g. 'E'
console.log('pushing');
filtered.push(item);
}
});
// code to match letter fragments, e.g. 'lan'
});
return filtered;
};
}]);
Ответы
Ответ 1
Это намного проще, используйте функцию String.indexOf()
:
angular.forEach(items, function(item) {
if( item.label.indexOf(searchText) >= 0 ) filtered.push(item);
});
Возможно, вы захотите повернуть обе строки .toLowerCase()
, чтобы выполнить нечувствительность к регистру:
searchText = searchText.toLowerCase();
angular.forEach(items, function(item) {
if( item.label.toLowerCase().indexOf(searchText) >= 0 ) filtered.push(item);
});
Ответ 2
angular.module('sgComponents').filter('listfilter',[ function () {
return function(items, searchText) {
var filtered = [];
var regex = new RegExp(".*" + searchItem + ".*", "ig");
angular.forEach(items, function(item) {
if(regex.test(item)){
filtered.push(item);
}
});
return filtered;
}
}]);
Ответ 3
Взгляните на директиву Angular -UI-Bootstrap для typeahead
, она делает именно то, что вы хотите: http://angular-ui.github.io/bootstrap/#/typeahead