Angular ui-select 仅过滤一个字段
Posted
技术标签:
【中文标题】Angular ui-select 仅过滤一个字段【英文标题】:Angular ui-select filtering only one field 【发布时间】:2015-01-22 02:35:30 【问题描述】:情况:
我有一个 Angular 应用程序,它使用 angular ui-select 从数据库中搜索和选择人员。
它工作正常,除了一件事。 用户应该能够使用两个条件在人员中进行过滤:姓名和电子邮件。
使用普通的角度过滤器,我只能过滤其中一个。 如果我尝试过滤这两个字段,它就不再起作用了。
一个字段的工作示例:
<ui-select multiple ng-model="database_people.selectedPeople" theme="select2" ng-disabled="disabled" style="width:100%">
<ui-select-match placeholder="Select person...">$item.name < $item.email ></ui-select-match>
<ui-select-choices repeat="person2 in list_people | filter: name: $select.search, db_data_type_id: 5">
<div ng-bind-html="person2.name | highlight: $select.search"></div>
<small>
email: <span ng-bind-html="''+person2.email | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
过滤器中有两个字段的示例无效:
<ui-select multiple ng-model="database_people.selectedPeople" theme="select2" ng-disabled="disabled" style="width:100%">
<ui-select-match placeholder="Select person...">$item.name < $item.email ></ui-select-match>
<ui-select-choices repeat="person2 in list_people | filter: name: $select.search, email: $select.search, db_data_type_id: 5">
<div ng-bind-html="person2.name | highlight: $select.search"></div>
<small>
email: <span ng-bind-html="''+person2.email | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
奇怪的是它实际上只对第一个字符有效。 当我键入第一个字符时,它会在名称和电子邮件这两个字段中突出显示它。 但是当我输入第二个字符时它不再起作用了 (我在控制台中没有错误)。
尝试使用来自 ANGULAR SAMPLES 的 PROPSFILTER:
<ui-select multiple ng-model="database_people.selectedPeople" theme="select2" ng-disabled="disabled" style="width:100%">
<ui-select-match placeholder="Select person...">$item.name < $item.email ></ui-select-match>
<ui-select-choices repeat="person2 in list_people | propsFilter: name: $select.search, email: $select.search, db_data_type_id: 5">
<div ng-bind-html="person2.name | highlight: $select.search"></div>
<small>
email: <span ng-bind-html="''+person2.email | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
在这种情况下,它完全崩溃了,select2 中没有数据了,我在控制台中遇到了一些错误:
Cannot read property 'toString' of null
Cannot read property 'length' of undefined
问题:
如何在多个字段中进行筛选? 我可以使用普通过滤器做到这一点吗? 或者我必须使用自定义过滤器? 但是在这种情况下,为什么不能正常工作?
非常感谢!
【问题讨论】:
@hanu 只是想知道,您是否为 propsFilter 实现了自定义 javascript 函数?它不会单独工作 (see line 83)。我还没有尝试使用它,但似乎很多人不知道他们必须包含 javascript 代码。 是的,它必须包含在指令中。谢谢指出。 【参考方案1】:您可以使用如下属性过滤器
<ui-select ng-model="emplyee" theme="bootstrap">
<ui-select-match placeholder="Select ...">$select.selected.firstName+" "+$select.selected.lastName</ui-select-match>
<ui-select-choices repeat="emp in employees | propertyFilter: firstName:$select.search, lastName:$select.search">
<span ng-bind-html="emp.firstName+' '+emp.lastName | highlight: $select.search"></span>
</ui-select-choices>
您必须像下面这样修改 propertyFilter:
.filter('propertyFilter', function($log)
return function(items, props)
var out = [];
if (angular.isArray(items))
items.forEach(function(item)
var itemMatches = false;
var keys = Object.keys(props);
var optionValue = '';
for (var i = 0; i < keys.length; i++)
optionValue = item[keys[i]] ? optionValue + item[keys[i]].toString().toLowerCase().replace(/ /g, '') : '';
for (var j = 0; j < keys.length; j++)
var text = props[keys[j]].toLowerCase().replace(/ /g, '');
if (optionValue.indexOf(text) !== -1)
itemMatches = true;
break;
if (itemMatches)
out.push(item);
);
else
// Let the output be the input untouched
out = items;
return out;
;
)
可以对整个选项值进行搜索。例如,如果在选项中您有“peter parker”,那么您可以使用“peter”、“parker”、“peter parker”、“peterparker”进行搜索,甚至可以在 peter parker 的任何字符之间使用多个空格进行搜索。
【讨论】:
【参考方案2】:可能是因为相同的值 ($select.search) 用于过滤器电子邮件和名称。
<ui-select-choices repeat="person2 in list_people | filter: name: $select.search, email: $select.search, db_data_type_id: 5">
...
这也将解释为什么它只适用于第一个字符。
为每个过滤器使用单独的值来解决这个问题:
<ui-select-choices repeat="person2 in list_people | filter: name: $select.search.name, email: $select.search.email, db_data_type_id: 5">
...
【讨论】:
抱歉,这应该如何工作?$select.search
是具有单个文本值的属性。
filter: name: $select.search, email: $select.search.. 对我来说很好..【参考方案3】:
我看到过一些类似 kunsingh 的答案的问题,这让我开始解决我的类似问题。在我的例子中,它在多个对象中搜索,但我也将逻辑删除的记录发送到客户端,并可选择在列表中过滤它们。对于下拉菜单,我希望始终将其删除,而无需更改 API。
这是我修改后的版本,其中包括搜索对象。显然,这只有在您的所有表都有一个名为 Deleted 的 int 列(对我来说是唯一键的一部分并在删除时设置为标识值)并且您将其传递给客户端时才有效。
稍后我计划进一步修改以允许递归搜索对象。
App.filter('dropdownFilter', function ()
return function (items, props: Object, keyvalue?)
var out = [];
if (angular.isArray(items))
items.forEach(function (item)
var itemMatches = false;
var canbreak = false;
// Filter out logically deleted records
if (item.Deleted != 0)
itemMatches = false;
else
var keys = Object.keys(props);
for (var i = 0; i < keys.length; i++)
var prop: string = keys[i];
var text = "";
// If an object, e.g. searching deep, such as Project: ProjectName: $select.search
// Then iterate through the object to find values.
// NOTE: This one searches one deep from each object,
// e.g. Project.ProjectName
// Project.User.LastName WILL NOT WORK.
if (angular.isObject(props[prop]))
angular.forEach(props[prop], function (value, key)
text = value.toLowerCase();
if (item[prop][key].toLowerCase().indexOf(text) !== -1)
itemMatches = true;
canbreak = true;
);
if (canbreak)
break;
// If it's a simple array, then woo!
else
text = props[prop].toLowerCase();
if (item[prop] != undefined && item[prop].toString().toLowerCase().indexOf(text) !== -1)
itemMatches = true;
break;
if (itemMatches)
out.push(item);
);
else
// Let the output be the input untouched
out = items;
return out;
);
及其使用中的示例(使用 select2 表示角度)。这是一个国家/国家的下拉列表,国家作为国家的子对象。
<ui-select ng-model="personneladdress.StateID" theme="select2" class="select2">
<ui-select-match placeholder="language.State">$select.selected.StateName</ui-select-match>
<ui-select-choices repeat="item.StateID as item in State | dropdownFilter: StateName: $select.search, Country: CountryName: $select.search">
<span ng-bind-html="item.StateName | highlight: $select.search"></span><br />
<small>
<span ng-bind-html="''+item.Country.CountryName | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
【讨论】:
你做了递归的吗? 我还没做,对不起!我已设法将所有列表子对象缩小到较小的大小。【参考方案4】:我通过使用这段代码解决了这个问题:
<ui-select-choices repeat="person2 in list_people | filter: $select.search" >
在 ui-select-match 我使用两个字段:
<ui-select-match placeholder="select One...">
$item.field1 - $item.field2
</ui-select-match>
【讨论】:
以上是关于Angular ui-select 仅过滤一个字段的主要内容,如果未能解决你的问题,请参考以下文章
需要 Node.js 和 Angular 来进行 ui-select
Angular UI-Select:如何为文本溢出添加工具提示?
Angular ui-select2 - 隐藏组件的初始绘图/渲染
如何将选项更改传递给 Angular-UI ui-select2?