【问题标题】:Angular filter a object by its propertiesAngular 通过其属性过滤对象
【发布时间】:2013-11-19 22:00:18
【问题描述】:

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

{
  "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>

但是,我知道一个行不通。

【问题讨论】:

    标签: javascript templates angularjs loops


    【解决方案1】:

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

    如果您想过滤给定对象的孙子(或更深),您可以继续构建您的对象层次结构。例如,如果要过滤“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 } }">
    

    【讨论】:

    • 我认为这是更好的答案。
    • 我相信这是在 v1.3 中添加的。现在绝对是更简单的方法。
    • 我确定这就是我要找的,但我不确定输入框的 ng-model。您能否也具体说明一下它的外观?
    • 这是最好的答案。谢谢。
    • 哦,谢谢我想出了解决方案。我应该这样使用它:var filteredThings = $filter('filter')($scope.things,$scope.properties.title);
    【解决方案2】:

    过滤器适用于数组,但你有一个对象字面量。

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

    如果您不需要这些索引值,那么转换为数组可能是您最好的选择( 这是数组工作的小提琴: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/

    【讨论】:

    • 我看到 Hugo 刚刚发布了一个更适合您的数据的过滤器。他避免了第二个循环,知道您的数据是如何结构化的。
    • 我迭代了我的对象,根据 type==="foo" 的条件将每个子对象推送到一个数组中,然后完全避免了过滤问题。过滤器仅适用于数组的信息对我非常有用,谢谢。
    【解决方案3】:

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

    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 中。希望我错了:)
    【解决方案4】:

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

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

    在 HTML 标记中:

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

    【讨论】:

    • 我实际上尝试过类似的事情,通过在 ctrl 上创建一个自定义过滤器,打印出控制台日志然后返回 obj,但似乎我的过滤器甚至没有生效,因为没有我曾经打印过的日志。
    • 我发现了一个问题:过滤器适用于数组,请参阅文档 - docs.angularjs.org/api/ng.filter:filter 和这个工作小提琴 jsfiddle.net/4YLH3/2
    • 小心使用它。您将无法使用!,您必须创建另一个函数,如果您使用!,它将导致 angular 返回奇怪的结果,有时有效,有时则无效。
      {{item.type}}
    • 我在很长一段时间后找到了这个解决方案。它对我的功能有更多帮助。 $scope.onetoTwentyFilter = function(item) { return ((item.price >1) && item.price
    【解决方案5】:

    试试这个过滤对象

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

    【讨论】:

      【解决方案6】:

      不需要这一切。此解决方案无需转换或创建您自己的过滤器即可正常工作:

       {{myModel.userSelectedHour["Start"]}}
      

      因此,object.["property"] 而不是 object.property。

      【讨论】:

        猜你喜欢
        • 2019-01-17
        • 1970-01-01
        • 2019-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-16
        • 1970-01-01
        相关资源
        最近更新 更多