我在页面上添加了一个简单的排序。我们的想法是搜索产品。这些产品以西班牙语编写并具有重音。例如:'Jamón'。
这是我的代码:
<div class="form-inline">
<label>Search</label>
<input type="text" ng-model="q"/>
</div>
<div ng-repeat="product in products_filtered = (category.products | filter:q | orderBy:'name')">
....
</div>
我唯一的问题是你必须输入“Jamón”才能找到产品“Jamón”。我想要的是更灵活,如果用户输入“Jamon”,结果必须包括“Jamón”。
如何使用角度过滤器进行搜索并忘记重音?有什么想法吗?
提前致谢。
答案 0 :(得分:8)
您需要创建过滤功能(或完整过滤器)。这是最简单的事情:
<强> HTML 强>
<div ng-app ng-controller="Ctrl">
<input type="text" ng-model="search">
<ul>
<li ng-repeat="name in names | filter:ignoreAccents">{{ name }}</li>
</ul>
</div>
<强>的Javascript 强>
function Ctrl($scope) {
function removeAccents(value) {
return value
.replace(/á/g, 'a')
.replace(/é/g, 'e')
.replace(/í/g, 'i')
.replace(/ó/g, 'o')
.replace(/ú/g, 'u');
}
$scope.ignoreAccents = function(item) {
if (!$scope.search) return true;
var text = removeAccents(item.toLowerCase())
var search = removeAccents($scope.search.toLowerCase());
return text.indexOf(search) > -1;
};
$scope.names = ['Jamón', 'Andrés', 'Cristián', 'Fernán', 'Raúl', 'Agustín'];
};
jsFiddle here。
请注意,这仅适用于字符串数组。如果要过滤对象列表(并在每个对象的每个属性中搜索,如Angular那样),则必须增强过滤器功能。我想这个例子应该让你开始。
答案 1 :(得分:3)
JavaScript有一个很好的功能,称为localeCompare
,您可以在其中指定sensitivity = base
,这个选项可以将á
和a
视为等效,{{ 3}}。我认为您唯一的选择是创建一个过滤函数,其中您手动规范化两个字符串(将ó
替换为o
,依此类推)并比较结果。
答案 2 :(得分:2)
以上是一个稍微增强的版本(当然不包括它搜索的额外外来字符)。我把它直接放到我的控制器中,它允许我搜索我想要搜索的所有数据。感谢Bernardo对此的投入!
希望能帮助别人。
function removeAccents(value) {
return value
.replace(/á/g, 'a')
.replace(/â/g, 'a')
.replace(/é/g, 'e')
.replace(/è/g, 'e')
.replace(/ê/g, 'e')
.replace(/í/g, 'i')
.replace(/ï/g, 'i')
.replace(/ì/g, 'i')
.replace(/ó/g, 'o')
.replace(/ô/g, 'o')
.replace(/ú/g, 'u')
.replace(/ü/g, 'u')
.replace(/ç/g, 'c')
.replace(/ß/g, 's');
}
$scope.ignoreAccents = function (item) {
if ($scope.search) {
var search = removeAccents($scope.search).toLowerCase();
var find = removeAccents(item.name + ' ' + item.description+ ' ' + item.producer+ ' ' + item.region).toLowerCase();
return find.indexOf(search) > -1;
}
return true;
};
答案 3 :(得分:2)
@Michael Benford提出的方法有一个很大的缺点:它是一个有状态的过滤器。这种做法是strongly discouraged by angular。此外,该方法不适用于深度数组和对象。
我更喜欢扩展标准角度滤镜:
<强> HTML:强>
<div ng-app ng-controller="Ctrl">
<input type="text" ng-model="search">
<ul>
<li ng-repeat="person in people | filter: search : searchFn">{{ person.names }} {{ person.surnames }}</li>
</ul>
</div>
<强>使用Javascript:强>
function Ctrl($scope) {
$scope.people = [{names: 'Jose', surnames: 'Benítez'}, {names: 'José María', surnames: 'Núñez Rico'}, {names: 'Rodrigo', surnames: 'Núñez'}];
$scope.searchFn = function(actual, expected) {
if (angular.isObject(actual)) return false;
function removeAccents(value) {
return value.toString().replace(/á/g, 'a').replace(/é/g, 'e').replace(/í/g, 'i').replace(/ó/g, 'o').replace(/ú/g, 'u').replace(/ñ/g, 'n');
}
actual = removeAccents(angular.lowercase('' + actual));
expected = removeAccents(angular.lowercase('' + expected));
return actual.indexOf(expected) !== -1;
}
}
答案 4 :(得分:1)
检查here以获取解决方案,以过滤对象列表并在每个对象的每个属性中搜索关键字。它还保持像搜索一样的角度,也可以搜索带/不带重音字符。
以下是过滤器定义: -
// ignore accents filter
$scope.ignoreAccents = function (item) {
if (!$scope.search) return true;
var objects = [];
var jsonstr = JSON.stringify(item);
var parsejson = JSON.parse(jsonstr);
var searchterm = $scope.search.replace(/[!#$%&'()*+,-./:;?@[\\\]_`{|}~]/g, ''); // skip replace if not required (it removes special characters)
objects = getNoOfResults(parsejson, searchterm);
return objects.length > 0;
};