过滤器如何在AngularJS中工作?

时间:2017-05-02 10:32:02

标签: angularjs angularjs-ng-repeat

我有一个用ng-repeat生成的表(来自对象的数组)。

我想用搜索文字字段过滤它。

我的数组中包含的对象具有深层属性。

我不知道为什么以及怎么做,但过滤器仅适用于电子邮件字段,与其他属性一样深。

我正在使用此搜索表单:

<input type="text" name="search" ng-model="searchText" />
...
<tr ng-repeat="x in obj | filter:searchText track by $index">
  ...
</tr>

plunker

编辑:

This answer帮助我理解为什么它不起作用。 有人知道我如何绕过过滤器中的$验证?

我正在使用 $ ,因为我正在使用Google Contact API格式。

6 个答案:

答案 0 :(得分:5)

您可以查看ngFilter here的源代码 设置为忽略以$开头的键,因为它是AngularJS用于公共($)和私有($$)属性的前缀。

答案 1 :(得分:3)

$是Angular内部属性使用的前缀。由于技术原因,Angular会阻止您使用它。以下是在不更改JSON对象的情况下处理$属性名称的解决方法:

您可以在Object.keys($scope.object)而非$scope.object上重复ng-repeat。

Demo on JSFiddle

答案 2 :(得分:2)

由于很明显我们既不能更改第三方API也不能更改AngularJS库代码,我们可以将对象键修改为开头没有$ 。但是,由于数据在很多层面都有很多,所以我们可以递归! :)

这是怎么回事。我将重新映射$scope.obj数组中的每个对象来调用函数:

$scope.obj = $scope.obj.map(function(cur) {
  return renameKey(cur)
})

现在,在renameKey内,它将使用辅助函数检查它是Array还是Object,并在替换为x开头的字符串之前递归调用自身与$

function renameKey(cur) {
  if(isArray(cur)) {
    cur.forEach(function(obj) {
      obj = renameKey(obj)
    })
  } else if (isObject(cur)) {
    for (let key in cur) {
      if(key.charAt(0) === '$') {
        cur['x'+key] = cur[key];
        delete cur[key];
      }
      cur[key] = renameKey(cur[key])
    }
  } 
  return cur
}

function isObject(obj) {
   return obj && (typeof obj === "object");
}

function isArray(obj) { 
  return isObject(obj) && (obj instanceof Array);
}

看起来很少,但确实有效!现在,我们需要做的只是在HTML中使用x$t而不是$t,并且热潮!

working plunker

答案 3 :(得分:1)

我无法发表评论,因为我的声誉低于50但是据我所知,任何有$ in的名字都没有在过滤器中使用。我尝试更改属性名称,这解决了问题。意识到你可以控制或不控制它。

答案 4 :(得分:1)

email有效,因为嵌套属性address不包含任何$个字符。

不幸的是,我认为没有办法绕过这种行为,但您可以制作自己的过滤器并在ng-repeat中使用它。

这是一个适合您的简单示例:

<强> JS

app.filter('customFilter', function() {
  return function(items, keyword) {
    if (!keyword || keyword.length === 0) return items;

    return items.filter(function(item){
      var phrase = keyword.$.toLowerCase();
      return item.gd$name.gd$fullName.$t.toLowerCase().includes(phrase) || 
        item.gd$name.gd$familyName.$t.toLowerCase().includes(phrase) || 
        item.gd$name.gd$givenName.$t.toLowerCase().includes(phrase) ||
        item.gd$email[0].address.toLowerCase().includes(phrase) ||
        item.gd$phoneNumber[0].$t.toLowerCase().includes(phrase) ||
        (!!item.gd$organization[0].gd$orgTitle && item.gd$organization[0].gd$orgTitle.$t.toLowerCase().includes(phrase)) ||
        (!!item.gd$organization[0].gd$orgName && item.gd$organization[0].gd$orgName.$t.toLowerCase().includes(phrase));
    });
  }
});

<强> HTML

<tr ng-repeat="x in obj | customFilter:searchText">

当然,您必须为可能的null值添加更多检查。我只是想让它能够处理您提供的数据。

希望,你会发现它很有用。

此处plunk

答案 5 :(得分:-1)

假设您的obj如下:

$scope.obj=[{firstName:'Jeet',lastName:'kumar'},{firstName:'test1',lastName:'dev'},{firstName:'test2',lastName:'other'}];

搜索输入框

<input type="text" name="search" ng-model="searchText" />

数据表按索引'firstName'过滤

<tr ng-repeat="x in obj | filter:{firstName:searchText}">
 <td>{{x.firstName}}</td>
<td>{{x.lastName}}</td>
</tr>

所有索引的数据表过滤器

<tr ng-repeat="x in obj | filter:searchText">
 <td>{{x.firstName}}</td>
<td>{{x.lastName}}</td>
</tr>

说明:

filter:{name:searchText}
filter on the basis of 'firstName' index from your $socpe.obj array