Angularjs:过滤JSON

时间:2015-01-30 07:38:12

标签: json angularjs angularjs-ng-repeat

我必须处理的json响应的结构给了我各种麻烦。 我想基于entityType字段过滤子元素。

例如,我只想要文件夹类型的元素。

JSON:

{
"id" : "df1d2550-1442-41b8-9588-785e229c5728",
"path" : "",
"name" : "",
"entityType" : "Folder",
"children" : {
    "child1" : {
        "id" : "02427ae5-364e-47d0-8998-0876c596d586",
        "name" : "child1",
        "entityType" : "Book"
    },
    "child2" : {
        "id" : "2bcef8b3-d3a3-410e-a481-a69ec7dce24d",
        "name" : "child2",
        "entityType" : "Letter"
    },
    "child3" : {
        "id" : "12ee8334-d596-4b59-a09d-c286117f3966",
        "name" : "child2",
        "entityType" : "Book"
    },
    "Art" : {
        "id" : "e3f2980e-433c-4eaa-b444-ed9702949ffc",
        "name" : "Art",
        "entityType" : "Folder"
    },
    "English" : {
        "id" : "8fe0f14a-6f76-41aa-9ab3-3e63cd5a900b",
        "name" : "English",
        "entityType" : "Folder"
    }
},
"properties" : { },
"ancestors" : [ ]
};

JS代码:

 $scope.isFolder = function(item) {
    return item.entityType === "Folder";
};

HTML

<div ng-repeat="item in library.children | filter:isFolder">
   <pre>{{item.name}} - {{item.entityType}}</pre>
</div>

当我只想要2时,此代码将显示所有孩子。 知道我做错了吗?

Plunker

由于

3 个答案:

答案 0 :(得分:1)

您的过滤器不起作用的原因是过滤器适用于数组,但您有一个对象文字。

因此,您可以将对象文字转换为如下数组:

{
"id" : "df1d2550-1442-41b8-9588-785e229c5728",
"path" : "",
"name" : "",
"entityType" : "Folder",
"children" : [
    {
        "id" : "02427ae5-364e-47d0-8998-0876c596d586",
        "name" : "child1",
        "entityType" : "Book"
    },
    {
        "id" : "2bcef8b3-d3a3-410e-a481-a69ec7dce24d",
        "name" : "child2",
        "entityType" : "Letter"
    },
    {
        "id" : "12ee8334-d596-4b59-a09d-c286117f3966",
        "name" : "child2",
        "entityType" : "Book"
    },
    {
        "id" : "e3f2980e-433c-4eaa-b444-ed9702949ffc",
        "name" : "Art",
        "entityType" : "Folder"
    },
    {
        "id" : "8fe0f14a-6f76-41aa-9ab3-3e63cd5a900b",
        "name" : "English",
        "entityType" : "Folder"
    }
],
"properties" : { },
"ancestors" : [ ]
};

您可以使用以下代码将children的属性转换为数组:

var arr = [];
for (var key in library.children) {
    if (obj.hasOwnProperty(key)) {
        obj[key]["key"] = key
        arr.push(obj[key]);
    }
};
library.children = arr;

或创建自己的过滤器,而不是像callum linington那样接受对象文字。

答案 1 :(得分:0)

我浏览了文档。虽然它没有您期望的那样明确,但看起来过滤器函数只适用于Array元素而不是对象。

在您的示例中,library.children是一个对象,而不是一个数组。因此,永远不会调用过滤器函数(您可以通过在函数内添加控制台语句来检查)。

文档中提到在Array上调用过滤器功能的特定部分可以找到here。您将在“参数”部分的“表达式”行中找到它 - 查找function描述。它表示该函数是在Arrays而不是Objects上调用的,这是你的场景。

答案 2 :(得分:-1)

因此,您可以通过编写自己的过滤器轻松解决此问题,这是您的自适应plnkr

简单过滤器:

app.filter('byKey', function () {
  return function (array, key, value) {
    var take = [];
    angular.forEach(array, function (e) {
      if (e[key] === value){
        take.push(e);
      }
    });

    return take;
  }
});

简单用法:

<div ng-repeat="item in library.children | byKey: 'entityType' : 'Folder'">
   <pre>{{item.name}} - {{item.entityType}}</pre>
</div>

细分:

return function (input, arg1.....argn) {

}

过滤器中的上述返回功能是驱动过滤器的内容,输入是您在|(管道)左侧指定的内容,在您的情况下:item in library.children

让人困惑的是正确的一面。第一个字符串应该是过滤器名称,在我的情况下是byKey,因为这就是我的命名。每次使用:时,您都可以通过arg

所以,我已经指定了这个:

return function (array, key, value) {}

第一个参数 - array,由|的左侧指定。每次使用args时,都会指定剩余的:

byKey : 'entityType' : 'Folder'

byKey = filter,&#39; entityType&#39; = key,&#39; Folder&#39; =键的值