【问题标题】:Angularjs: Filtering JSONAngularjs:过滤 JSON
【发布时间】:2015-01-30 07:38:11
【问题描述】:

我必须使用的 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

谢谢

【问题讨论】:

标签: json angularjs angularjs-ng-repeat


【解决方案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 那样接收对象字面量。

【讨论】:

  • @callmekatootie ...你很有趣
  • 伙计们,放松。我们想做的就是帮助人们,我认为任何帮助都应该得到赞赏。
  • 谢谢你说得通。我知道这与 json 的格式有关,但不太确定如何。
  • @kriek 我已经更新了我的答案,你可以使用新添加的sn-p将children的属性转换为数组。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    所以你可以通过编写自己的过滤器轻松解决这个问题,这里是你改编的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) {}
    

    第一个参数 - 数组,由| 的左边指定。其余的args 是在您每次使用: 时指定的,在您的情况下

    byKey : 'entityType' : 'Folder'
    

    byKey = filter, 'entityType' = key, 'Folder' = key的值

    【讨论】:

    • 问题不是关于替代解决方案 - 问题是为什么 OP 的代码不起作用
    • 所以答案是,因为你必须创建一个自定义过滤器.....无论如何他有问题,我只是提供一个解决方案 - 替代解决方案非常适合帮助人们了解他们的问题。这种情况可能是 OP 不知道您可以创建过滤器,并且现在喜欢它更容易的事实。 @callmekatootie 这个社区是关于分享答案、方法和解决方案的。我只是贡献。
    • @callmekatootie 更多,并非所有问题都要求替代解决方案,这可能有几个原因。特别是出于一个原因,我将始终发布“替代”解决方案,因为 OP 可能不知道有不同的做某事的方式。我没有机会知道 OP 知道什么,所以我只是尽我所能帮助他。我的方法行得通,如果这是他想要的,那很好,如果不是,那很好。至少我试过帮助他。
    • 在这种情况下,您可以询问 OP 是否需要其他方式。
    • 这有什么意义,他要求回答。我提供了一个。完毕。没有错。这个论坛应该是关于鼓励其他人的,如果你想批评某人或某事 - 对自己动手。
    猜你喜欢
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    相关资源
    最近更新 更多