如何使用AngularJS过滤数组并将过滤对象的属性用作ng-model属性?


121

如果我有一个对象数组,并且想将Angular模型绑定到基于过滤器的元素之一的属性,该怎么做?我可以用一个具体的例子更好地解释:

HTML:

<!DOCTYPE html>
<html ng-app>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
        <meta charset=utf-8 />
        <title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
        <input ng-model="results.year">
        <input ng-model="results.subjects.title | filter:{grade:'C'}">
    </body>
</html>

控制器:

function MyCtrl($scope) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
}

JSBin:http//jsbin.com/adisax/1/edit

我想将第二个输入过滤为具有'C'等级的主题,但是我不想将模型绑定到该等级;我想将其绑定到等级为“ C”的主题的标题

这可能吗?如果可以,怎么做?

Answers:


127
<div ng-repeat="subject in results.subjects | filter:{grade:'C'}">
    <input ng-model="subject.title" />
</div>

1
我知道你要去哪里,但我真的不想要中继器。我实际上要过滤的属性是一个标识列,因此它是唯一的。但是我看到这将是解决通用问题的正确方法。
2013年


10
这非常有帮助,并且对于逆(除C之外的所有其他值)而言,这将起作用:filter:{grade:'!'+'C'}
pulkitsinghal,2015年

2
你可以用grade array吗?就我而言,我从树状视图构建成绩数组,并希望为数组中的结果过滤结果。
Juan Carlos Oropeza

157

您可以在控制器中使用“过滤器”过滤器来获得所有“ C”等级。获取结果数组的第一个元素将为您提供等级为“ C”的主题的标题

$scope.gradeC = $filter('filter')($scope.results.subjects, {grade: 'C'})[0];

http://jsbin.com/ewitun/1/edit

与普通ES6相同:

$scope.gradeC = $scope.results.subjects.filter((subject) => subject.grade === 'C')[0]

对不起,我没有关注第二个过滤器(“过滤器”),您能再解释一个吗?
Winnemucca

1
@stevek这是过滤器的名称。filter()方法为您提供过滤器。只是将过滤器称为过滤器是因为它过滤数组。使用货币过滤器时,它看起来像这样:$ filter('currency')(amount,symbol,fractionSize)在此处检查文档:docs.angularjs.org/api/ng/filter
Oliver


13

请注意,如果您使用$ filter这样的话:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

而且您碰巧获得了另一个等级,哦,我不知道,CC或AC或C +或CCC会吸引他们。您需要附加一个完全匹配的要求:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'}, true);

当我提出一些佣金详细信息时,这真让我丧命:

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}))[0];

仅因出现错误而被调用,因为它引入了佣金ID 56而不是6。

添加true会强制完全匹配。

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}, true))[0];

但是,我还是喜欢这个(我使用打字稿,因此使用“ Let”和=>):

let obj = this.$filter('filter')(this.CommissionTypes, (item) =>{ 
             return item.commission_type_id === 6;
           })[0];

我这样做是因为,在将来的某个时刻,我可能想从过滤的数据中获取更多信息,等等。


我有和您一样的错误,感谢第三个布尔参数的提示。没意识到。
Georg Leber

12

如果要在控制器中创建结果的单独列表,则可以应用过滤器

function MyCtrl($scope, filterFilter) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
  //create a filtered array of results 
  //with grade 'C' or subjects that have been failed
  $scope.failedSubjects = filterFilter($scope.results.subjects, {'grade':'C'});
}

然后,您可以使用引用结果对象的相同方式引用failSubjects

您可以在这里阅读更多有关它的信息 https://docs.angularjs.org/guide/filter

由于此答案已更新了文档,因此他们现在建议调用过滤器

// update 
// eg: $filter('filter')(array, expression, comparator, anyPropertyKey);
// becomes
$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

什么是filterFilter?有任何服务或指示吗?filterFilter的代码在哪里?

这是一项有角度的服务。请看上面链接中的第一个示例。(在scripts.js文件中)
Kieran

尽管他们更改了文档filterFilter仍然有效。.–
Kieran

4

您还可以函数用于$filter('filter')

var foo = $filter('filter')($scope.results.subjects, function (item) {
  return item.grade !== 'A';
});

4

如果您使用的是ES6,则可以:

var sample = [1, 2, 3]

var result = sample.filter(elem => elem !== 2)

/* output */
[1, 3]

还要注意,过滤器不会更新现有阵列,它每次都会返回一个新的过滤阵列。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.