如何在 AngularJs 的 ng-repeat 中通过数组筛选?

5
我正在使用ng-repeat来显示我的数据,这部分工作得很好。
我的ng-repeat结果集中的一个数据字段是项的数组。 例如:{x:1, y:[2,3,4]} 我希望通过数组内的数据来过滤数据。我可以轻松地通过非数组数据进行过滤,但是当我尝试通过查找数组内部时,我遇到了麻烦。
以下是我的标记 ng-repeat = "con in cons | filter: usrSingle.username in con.conPlayerList" (编辑标记以更好地匹配我的示例 ng-repeat = "con in cons | filter: '3' in con.y" ) usrSingle是此控制器中可以访问的作用域。我没有收到任何错误信息,也找不到此类示例。
有人要求更多代码,下面是它。我忘了提到这是一个MEAN应用程序。我使用MongoDB提供数据。我对数据调用使用REST API。
(编辑)来自angular模块的代码:
// call to the api for data
app.factory('usrService', function ($resource) {
return $resource('/api/users', {});
});
// factory to hold user data between controllers
app.factory('usrTracker', function () {
var vUsrProfile = {
    usrSingle: 'usrSingle'
};
return {
    getProperty: function () {
        return vUsrProfile;
    },
    setProperty: function (value) {
        vUsrProfile = value;
    }
};
});
// angular controller
app.controller('usrPageController', function ($scope, usrTracker, conService, postService) {

var usrSingle = usrTracker.getProperty();
$scope.usrSingle = usrSingle;
$scope.cons = conService.query();
$scope.posts = postService.query();
});

(最终编辑)此答案对于这个问题是一个很好的解决方案。但我选择了另一条路。我使用了mongoDB的$unwind聚合来展开我的数据,如下所示。

API文件中的代码:

// get
.get(function (req, res) {
// unwind on the conPlayerList array field
Con.aggregate([{ $unwind: "$conPlayerList" }], function (err, cons) {
return res.json(cons);
});
})

然后我按照我要查找的用户进行了筛选。将HTML Angular标记更改为:

ng-repeat="con in cons | filter:{conPlayerList:usrSingle.username}"

为了更好地匹配我的示例,通过删除我的特定代码,它应该是:

ng-repeat="con in cons | filter: {y:'3'} "


1
你最好自己编写过滤函数。考虑使用辅助库,如lodash(underscore)。 - Constantine Poltyrev
请您提供更多的代码,这样就可以更容易地找到不同的解决方案来解决您的问题。您可能根本不需要使用过滤器。 - ArslanW
我认为这需要一个单独的过滤器。我可以做到,但我想知道是否有一种方法可以查看由ng-repeat命令返回的数组内部。似乎很有可能在ng-repeat中的数据具有数组字段。 - Trewaters
没有任何视图语法可以在没有过滤函数的情况下完成这个任务。 - charlietfl
我对Angular还很陌生,所以我想确保自己没有错过什么简单的东西。过滤器函数是处理这些问题的绝佳选择。 - Trewaters
1个回答

4
你可以在数组上使用Angular内置的过滤器逻辑,但请注意这不是精确匹配,并且会针对数组条目300进行匹配,如果usrSingle设置为3,请参见Fiddle中的示例。
<div ng-repeat = "con in cons | filter:{y:usrSingle} ">...</div> 

为了精确匹配数组元素,您可以在控制器上使用filter和谓词函数,例如:

控制器(Fiddle):

app.controller('usrPageController', function ($scope) {
  $scope.filterFn = filterFn;
  $scope.usrSingle = 3;
  $scope.cons = [
      {x:0, y:[1,2,3]},
      {x:1, y:[2,3,4]},
      {x:2, y:[3,4,5]},
      {x:3, y:[4,5,6]},
      {x:4, y:[5,6,7]}
  ];

  function filterFn(con){
    return con.y.indexOf($scope.usrSingle) > -1;
  }
});

查看:

<div ng-repeat = "con in cons | filter:filterFn">...</div>

或者,您可以创建一个自定义过滤器,在应用程序的其他地方重复使用,并将usrSingle作为参数传入:

过滤器(Fiddle):

app.filter('customFilter', function() {
  return function(input, value) {
    var result = [];
    input.forEach(function(item){
        if(item.y.indexOf(value) > -1){
            result.push(item);
        }
    });
    return result;
  };
});

视图:

<div ng-repeat = "con in cons | customFilter:usrSingle">...</div>

这是一个很好的解决方法,但不是我要找的答案。听起来在特定点进行过滤的唯一方法是使用自定义函数。我用我的代码测试了你的函数,控制器函数运行得非常好。我暂时会继续使用我的 MongoDB unwind,但我感谢你的回答和详细说明。谢谢。 - Trewaters
不用谢!啊,我更好地理解了你的问题 - 我更新了答案,并加入了另一个你可能会发现有用的例子。 - sheilak
@sheilak,你能帮我解决这个问题吗? - node_man

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接