AngularJS - 按任何属性过滤
AngularJS - Filter by any of the properties
我有一个应用程序,我在其中显示带有 AngularJS 的项目列表。我试图在此列表中进行简单搜索,但它会搜索该项目中的所有内容。项目示例:
{
id: 283727893,
name: 'Item A',
parent: {
id: 239495838,
name: 'Item B'
},
user: 'User C'
}
在列表中我只写了根项的名称,所以 parent.name
没有出现。
问题
但是,如果我使用 'Item B' 的 AngularJS 过滤器进行搜索,它仍然会出现,因为内部 属性 有这个字符串。
我试过的
我已经放置了一个对象引用,如下所示(其中 val
是输入的文本):
vm.searchObj = {
name: val,
user: val
};
然后,在我的 DOM:
<li data-ng-repeat="[...] | filter: Ctrl.searchObj | orderBy: Ctrl.orderBy">
...
</li>
但是,这适用于条件 AND,因此仅当 name
和 user
都具有 val
.
时才会显示
我需要的
我想获取输入文本并进行搜索以根据给定的对象属性(复数形式)过滤此列表。
所以,在这个例子中,如果我写 'Item A' 或 'User C'(或者只是 'A' 或只是 'C' 等等),这个项目应该出现,但是如果我写 'B' 就不会,因为 name
和 user
的 none 有这封信。
我需要它获取参考对象,在本例中为 Ctrl.searchObj
,并检查对象的任何给定属性是否包含 val
到过滤对象的相同结构中.
那,当然,应该工作到对象的更深层次,所以我可以定义 searchObj
如下,如果过滤后的对象内部有那个结构,仍然能够得到:
vm.searchObj = {
parent: {
name: 'Item'
}
};
在这种情况下,它应该显示其 parent.name
属性 包含单词 'Item' 的那些项目。
如果您需要更多信息,请告诉我!
谢谢!
如果我理解正确,正在搜索的对象(我们将其称为 target
)是匹配的,如果:
searchObj
和 target
至少有一个 属性 同级名字
target
的属性的值等于或包含searchObj
的属性的值
下面的代码(包括您的编辑)应该可以满足您的需要。我将留给您填写任何边缘情况(检查 hasOwnProperty
、不同类型的比较等)。我认为像这样的过滤应该只在必要时发生,比如当用户输入时。从中创建一个 Angular 过滤器可能过于昂贵,因为它在每个摘要周期中运行:
function objectContains(searchObj, target) {
for (var property in searchObj) {
var searchVal = searchObj[property];
var targetVal = target[property];
if (isObject(searchVal) && isObject(targetVal)) {
if(objectContains(searchVal, targetVal)){
return true;
}
}
if (
!isObject(searchVal) && !isObject(targetVal) &&
!isUndefinedOrNull(targetVal) &&
!isUndefinedOrNull(searchVal) &&
targetVal.toString().indexOf(searchVal.toString()) !== -1
) {
return true;
}
}
return false;
}
function isUndefinedOrNull(x) {
return typeof x === "undefined" || x === null;
}
function isObject(x) {
return typeof x === "object";
}
var filtered = list.filter(function(item) {
return objectContains(searchObj, item);
});
试试这个方法。在过滤器上使用 true
属性 以准确获取您搜索的内容!
<li data-ng-repeat="[...] | filter: Ctrl.searchObj:true | orderBy: Ctrl.orderBy">
...
</li>
因此,以 Frank Modica(谢谢你)的代码为基础,我在其 compare
功能上提出了一些版本,不仅可以查找第一个 属性 , 但如果这不匹配,请继续搜索。这是修改后的代码:
function objectContains(searchObj, target) {
for (var property in searchObj) {
var searchVal = searchObj[property];
var targetVal = target[property];
if (isObject(searchVal) && isObject(targetVal)) {
if(objectContains(searchVal, targetVal)){
return true;
}
}
if (
!isObject(searchVal) && !isObject(targetVal) &&
!isUndefinedOrNull(targetVal) &&
!isUndefinedOrNull(searchVal) &&
targetVal.toString().indexOf(searchVal.toString()) !== -1
) {
return true;
}
}
return false;
}
万一它匹配,它 returns 正确,因为它只需要一个匹配项就是我们正在寻找的。如果不匹配,则继续。
我们检查第二个条件是否不是对象,因为当我们应用 toString()
时它们会变成 [object OBJECT]
,所以它 returns true
总是。这样,如果它是一个对象,它将忽略它(不需要做进一步的检查,因为我们已经在第一个 if
中完成了)。
谢谢弗兰克,因为我想不出这个!
现在,它完美运行了!
我有一个应用程序,我在其中显示带有 AngularJS 的项目列表。我试图在此列表中进行简单搜索,但它会搜索该项目中的所有内容。项目示例:
{
id: 283727893,
name: 'Item A',
parent: {
id: 239495838,
name: 'Item B'
},
user: 'User C'
}
在列表中我只写了根项的名称,所以 parent.name
没有出现。
问题
但是,如果我使用 'Item B' 的 AngularJS 过滤器进行搜索,它仍然会出现,因为内部 属性 有这个字符串。
我试过的
我已经放置了一个对象引用,如下所示(其中 val
是输入的文本):
vm.searchObj = {
name: val,
user: val
};
然后,在我的 DOM:
<li data-ng-repeat="[...] | filter: Ctrl.searchObj | orderBy: Ctrl.orderBy">
...
</li>
但是,这适用于条件 AND,因此仅当 name
和 user
都具有 val
.
我需要的
我想获取输入文本并进行搜索以根据给定的对象属性(复数形式)过滤此列表。
所以,在这个例子中,如果我写 'Item A' 或 'User C'(或者只是 'A' 或只是 'C' 等等),这个项目应该出现,但是如果我写 'B' 就不会,因为 name
和 user
的 none 有这封信。
我需要它获取参考对象,在本例中为 Ctrl.searchObj
,并检查对象的任何给定属性是否包含 val
到过滤对象的相同结构中.
那,当然,应该工作到对象的更深层次,所以我可以定义 searchObj
如下,如果过滤后的对象内部有那个结构,仍然能够得到:
vm.searchObj = {
parent: {
name: 'Item'
}
};
在这种情况下,它应该显示其 parent.name
属性 包含单词 'Item' 的那些项目。
如果您需要更多信息,请告诉我!
谢谢!
如果我理解正确,正在搜索的对象(我们将其称为 target
)是匹配的,如果:
searchObj
和target
至少有一个 属性 同级名字target
的属性的值等于或包含searchObj
的属性的值
下面的代码(包括您的编辑)应该可以满足您的需要。我将留给您填写任何边缘情况(检查 hasOwnProperty
、不同类型的比较等)。我认为像这样的过滤应该只在必要时发生,比如当用户输入时。从中创建一个 Angular 过滤器可能过于昂贵,因为它在每个摘要周期中运行:
function objectContains(searchObj, target) {
for (var property in searchObj) {
var searchVal = searchObj[property];
var targetVal = target[property];
if (isObject(searchVal) && isObject(targetVal)) {
if(objectContains(searchVal, targetVal)){
return true;
}
}
if (
!isObject(searchVal) && !isObject(targetVal) &&
!isUndefinedOrNull(targetVal) &&
!isUndefinedOrNull(searchVal) &&
targetVal.toString().indexOf(searchVal.toString()) !== -1
) {
return true;
}
}
return false;
}
function isUndefinedOrNull(x) {
return typeof x === "undefined" || x === null;
}
function isObject(x) {
return typeof x === "object";
}
var filtered = list.filter(function(item) {
return objectContains(searchObj, item);
});
试试这个方法。在过滤器上使用 true
属性 以准确获取您搜索的内容!
<li data-ng-repeat="[...] | filter: Ctrl.searchObj:true | orderBy: Ctrl.orderBy">
...
</li>
因此,以 Frank Modica(谢谢你)的代码为基础,我在其 compare
功能上提出了一些版本,不仅可以查找第一个 属性 , 但如果这不匹配,请继续搜索。这是修改后的代码:
function objectContains(searchObj, target) {
for (var property in searchObj) {
var searchVal = searchObj[property];
var targetVal = target[property];
if (isObject(searchVal) && isObject(targetVal)) {
if(objectContains(searchVal, targetVal)){
return true;
}
}
if (
!isObject(searchVal) && !isObject(targetVal) &&
!isUndefinedOrNull(targetVal) &&
!isUndefinedOrNull(searchVal) &&
targetVal.toString().indexOf(searchVal.toString()) !== -1
) {
return true;
}
}
return false;
}
万一它匹配,它 returns 正确,因为它只需要一个匹配项就是我们正在寻找的。如果不匹配,则继续。
我们检查第二个条件是否不是对象,因为当我们应用 toString()
时它们会变成 [object OBJECT]
,所以它 returns true
总是。这样,如果它是一个对象,它将忽略它(不需要做进一步的检查,因为我们已经在第一个 if
中完成了)。
谢谢弗兰克,因为我想不出这个!
现在,它完美运行了!