angularjs过滤深json对象

时间:2016-02-26 15:35:08

标签: javascript jquery angularjs json

我有以下格式的数据:

{
  "A": {
    "P": {
      "Age": {
        "keyName": "Repo1",
        "checked": false
      },
      "Gender": {
        "keyName": "Repo2",
        "checked": false
      }
    }
  },
  "S": {
    "D": {
      "keyName": "Repo3",
      "checked": false
    },
    "W": {
      "keyName": "Repo4",
      "checked": false
    }
  }
}

HTML:

<div ng-controller="MyController">
  <ul>
     <li ng-repeat="kName in keyNames">
      <input type="checkbox" value="{{kName.keyName}}" ng-click="selectedKeyNames($event, kName)"> {{kName.keyName}}
      </li>
  </ul>

  <pre>{{tempData | json}}</pre>
</div>

JS:

var myApp = angular.module('myApp', []);

myApp.controller('MyController',["$scope","$filter", function ($scope, $filter) {

  $scope.tempData = {"A":{"P":{"Age":{"keyName":"Repo1","checked":false},"Gender":{"keyName":"Repo2","checked":false}}},"S":{"D":{"keyName":"Repo3","checked":false},"W":{"keyName":"Repo4","checked":false}}};

$scope.keyNames = $filter("buildKeyMap")($scope.tempData);

$scope.selectedKeyNames = function(e, rpt){
  $scope.findNode($scope.tempData, "keyName", rpt.keyName, $(e.target).is(":checked"));

};

        $scope.findNode = function(obj, key, val, isChecked) {
            var objects = [];
            for (var i in obj) {
                if (!obj.hasOwnProperty(i)) continue;
                if (typeof obj[i] == 'object') {
                    objects = objects.concat($scope.findNode(obj[i], key, val, isChecked));
                } else if (i == key && obj[key] && obj[key] == val) {
                    obj.checked = isChecked;
                    $scope.foundObject = obj;
                    break;
                }
            }
            return $scope.foundObject;
        };

}]).filter("buildKeyMap",function(){
        return function(items){
            var options = []
            var recursiveFilter = function(items){
                angular.forEach(items, function(item, parentKey){
                    if(item.hasOwnProperty("keyName")){
                        options.push({"keyName": item.keyName});
                    }else{
                        recursiveFilter(item);
                    }
                });
            };
            recursiveFilter(items);
            return options;
        };
    });

我想只过滤那些check = true的节点。它应该是相同的json结构。我已经完成了checked = true但我无法从json中删除或添加节点。

这里是小提琴: http://jsfiddle.net/qsp4dwsd/5/ 设置checked = true但json在假或真的情况下保持不变

2 个答案:

答案 0 :(得分:1)

我可以更多地了解如何做到这一点,所以请随时给我留言,但简短的回答是在这个伟大的过滤器包中:

https://github.com/a8m/angular-filter#filterby

过滤有助于确切地说明您要执行的操作,但我建议您首先将顶级对象转换为数组。

collection | filterBy: [prop, nested.prop, etc..]: search: strict[optional]

希望这有帮助。

答案 1 :(得分:1)

我在这里创建了demo

整体变化:

  • 为复选框定义ng-model
  • 定义变量OrginalData
  • 更改了selectedKeyNames方法
  • 更改了findNode方法

<强> HTML

<div ng-controller="MyController">
  <ul>
     <li ng-repeat="kName in keyNames">
      <input type="checkbox" ng-model="kName.checked" value="{{kName.keyName}}" ng-click="selectedKeyNames()"> {{kName.keyName}}
      </li>
  </ul>

  <pre>{{tempData | json}}</pre>
</div>

<强> JS

var myApp = angular.module('myApp', []);

myApp.controller('MyController',["$scope","$filter", function ($scope, $filter) {      

var OriginalData ={"A":{"P":{"Age":{"keyName":"Repo1","checked":false},"Gender":{"keyName":"Repo2","checked":false}}},"S":{"D":{"keyName":"Repo3","checked":false},"W":{"keyName":"Repo4","checked":false}}}

$scope.tempData = $.extend(true, {}, OriginalData);

$scope.keyNames = $filter("buildKeyMap")($scope.tempData);

$scope.selectedKeyNames = function(e, rpt){ 
  $scope.tempData = $.extend(true, {}, OriginalData);
  for(var kName in $scope.keyNames){
   $scope.findNode($scope.tempData, "keyName", $scope.keyNames[kName].keyName, $scope.keyNames[kName].checked); 
   }
};

        $scope.findNode = function(obj, key, val, isChecked) { 
            for (var i in obj) {
                if (!obj.hasOwnProperty(i)) continue;
                if (typeof obj[i] == 'object') {
                $scope.findNode(obj[i], key, val, isChecked);
                } 
                else if (i == key && obj[key] && obj[key] == val)                               {                   
                        if(!isChecked) {
                        delete obj[i];
                      delete obj["checked"];
                     }
                    else
                        obj.checked = isChecked;
                    break;
                }
            }               
        };

}]).filter("buildKeyMap",function(){
        return function(items){
            var options = []
            var recursiveFilter = function(items){
                angular.forEach(items, function(item, parentKey){
                    if(item.hasOwnProperty("keyName")){
                        options.push({"keyName": item.keyName});
                    }else{
                        recursiveFilter(item);
                    }
                });
            };
            recursiveFilter(items);
            return options;
        };
    });