Angular 根据对象的属性过滤对象

IT技术 javascript templates angularjs loops
2021-03-17 01:07:56

我有一个具有以下类似结构的一系列对象属性的对象(这是数据从服务返回的方式):

{
  "1": {
    "type": "foo",
    "name": "blah"
  },
  "2": {
    "type": "bar"
  },
  "3": {
    "type": "foo"
  },
  "4": {
    "type": "baz"
  },
  "5": {
    "type": "test"
  }
}

当我执行 ng-repeat 时,我可以遍历所有 5 个对象,例如:

<div ng-repeat="item in items">{{item.type}}</div>

但是,我真正想做的是只迭代那些不是 "foo" 类型的项目,即 3 次迭代而不是 5 次。我知道可以以某种方式利用过滤器来做到这一点,但我不确定如何。我尝试了以下方法:

<div ng-repeat="item in items| !filter:{type:'foo'}">{{item.type}}</div>

但这不起作用。事实上,即使执行以下操作以限制为仅 2 个对象(那些带有 item.type==="foo" 的对象),它也不起作用并进行 5 次迭代:

<div ng-repeat="item in items| filter:{type:'foo'}">{{item.type}}</div>

本质上,我想做类似的事情:

<div ng-repeat="item in items" ng-if="item.type !=='foo'>{{item.type}}</div>

但是,我知道那是行不通的。

6个回答

回答有点晚,但这可能会有所帮助:

如果您想过滤给定对象的孙(或更深),您可以继续构建您的对象层次结构。例如,如果您想过滤“thing.properties.title”,您可以执行以下操作:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter } }">

您还可以通过将对象的多个属性添加到过滤器对象中来过滤它们:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter, id: id_filter } }">

'not equals' 的语法有点不对,请尝试以下操作:

<div ng-repeat="thing in things | filter: { properties: { title: '!' + title_filter } }">
在我看来,这是更好的答案。
2021-04-30 01:07:56
这是最好的答案。谢谢。
2021-05-02 01:07:56
我相信这是在 v1.3 中添加的。现在绝对是更简单的方法。
2021-05-03 01:07:56
哦,谢谢我想出了解决方案。我应该像这样使用它:var filteredThings = $filter('filter')($scope.things,$scope.properties.title);
2021-05-09 01:07:56
我确定这就是我要找的东西,但我不确定要为输入框放置的 ng-model。您还可以指定它的外观吗?
2021-05-17 01:07:56

过滤器适用于数组,但您有一个对象文字。

因此,您可以将对象文字转换为数组,也可以创建自己的过滤器而不是接受对象文字。

如果您不需要这些索引值,那么转换为数组可能是您最好的选择(这是数组工作的小提琴:http : //jsfiddle.net/NqA8d/3/):

$scope.items = [{
    "type": "foo",
        "name": "blah"
}, {
    "type": "bar"
}, {
    "type": "foo"
}, {
    "type": "baz"
}, {
    "type": "test"
}];

如果您想做一个过滤器,这是一种方法:

myApp.filter('myFilter', function () {
    return function (items, search) {
        var result = [];
        angular.forEach(items, function (value, key) {
            angular.forEach(value, function (value2, key2) {
                if (value2 === search) {
                    result.push(value2);
                }
            })
        });
        return result;

    }
});

那个小提琴:http : //jsfiddle.net/NqA8d/5/

我迭代了我的对象,根据 type==="foo" 的条件将每个子对象推入一个数组,然后完全避免了过滤问题。过滤器仅适用于数组的信息对我来说非常有用,谢谢。
2021-04-23 01:07:56
我看到 Hugo 刚刚发布了一个与您的数据更匹配的过滤器。他避免了第二个循环,知道您的数据是如何构建的。
2021-04-24 01:07:56

虽然我同意转换您的对象可能是这里的最佳选择,但您也可以使用此过滤器功能:

angular.module('app').filter('objectByKeyValFilter', function () {
return function (input, filterKey, filterVal) {
    var filteredInput ={};
     angular.forEach(input, function(value, key){
       if(value[filterKey] && value[filterKey] !== filterVal){
          filteredInput[key]= value;
        }
     });
     return filteredInput;
}});

像这样:

<div ng-repeat="(key, value) in data | objectByKeyValFilter:'type':'foo'">{{key}}{{value.type}}</div> 

另见Plunker

这真的很有用,谢谢!我最终将其更改为过滤匹配而不是不匹配的内容。不知道为什么像这样的东西还没有内置到 Angular 中。希望我错了:)
2021-04-25 01:07:56

试试这个(在控制器中):

$scope.notFooFilter = function(item)
{
    return (item.type !== 'foo');
};

在 HTML 标记中:

<div ng-repeat="item in items| filter:notFooFilter">{{item.type}}</div>
小心使用这个。您将无法使用 !,您必须创建另一个函数,如果您使用 !,它会导致 angular 返回奇怪的结果,有时有效,有时无效。<div ng-repeat="item in items| filter:!notFooFilter">{{item.type}}</div>
2021-04-22 01:07:56
很长时间后我找到了这个解决方案。它对我的功能有更多帮助。$scope.onetoTwentyFilter = function(item) { return ((item.price >1) && item.price < 20); };
2021-05-04 01:07:56
我发现了一个问题:过滤器与数组一起工作,请参阅文档 - docs.angularjs.org/api/ng.filter:filter和这个工作小提琴jsfiddle.net/4YLH3/2
2021-05-05 01:07:56
实际上,我之前尝试过类似的方法,通过在 ctrl 上创建一个自定义过滤器来打印控制台日志,然后返回 obj,但似乎我的过滤器甚至没有生效,因为我的任何日志都没有打印过。
2021-05-07 01:07:56

试试这个过滤对象

var rateSelected = $filter('filter')($scope.GradeList, function (obj) {
                        if(obj.GradeId == $scope.contractor_emp.save_modal_data.GradeId)
                        return obj;
                });