AngularJS - 使用多级JSON进行过滤

时间:2015-11-01 15:41:06

标签: json angularjs angular-filters

我在JSON中有一个复杂的数据集,其中包括本质上是分层的位置数据,其中包含区域的父级,州/国家/省的子obj以及城市的子子obj。我正在尝试过滤每个数据部分。

其他值(阶段和数字)上的过滤器可以正常工作,但位置数据却没有。我假设它是因为该数据的分层性质,但是我找不到Angular中的层级数据的任何过滤示例来弄清楚我做错了什么。

Plunkr:http://plnkr.co/edit/vaKU7l?p=preview

var app = angular.module('plunker', ['angular.filter']);

app.controller('MainCtrl', function($scope, $anchorScroll, $location, $http) {

	$scope.cart = [];

	$scope.addToCart = function(index) {
		$scope.cart.push(index);

		$scope.cartCount = $scope.cart.length;
	}



	$scope.activeRow = function(index) {
		$scope.selectedRow = index;

		$location.hash();
		$anchorScroll('anchor-' + index);

	}


	$scope.gotoAnchor = function(x) {
		var newHash = 'anchor' + x;


	}
    
        // GET data
        $scope.dataObject = data.List;
        $scope.locationObject = data.Locations;


});
body{background:#eee;}
div.cart{display:block;height:70px;background:silver;margin-left:20px;width:200px;padding:5px 10px;margin-bottom:20px;margin-top:20px;}
.cart h1{color:#fff;line-height:20px;}
.item-list-wrapper{height:400px;width:90%;border:1px solid #ddd;overflow-y:scroll;margin-left:20px;}
.item-list-wrapper table td{padding:10px;vertical-align:middle;margin-bottom:10px;font-size:12px;}
.item-list{height:auto;width:100%;margin-bottom:10px;box-shadow:0 2px 2px rgba(0,0,0,0.2);border:1px solid #fff;background:#efefe4;}
.col-num{width:100px;}
.col-compound{width:80px;}
.filters{width:100%;clear:both;margin-left:20px;}
.filters select{width:200px;}
.filters column{height:100px;width:200px;display:inline-block;margin:0;padding:0;}
.filters select{display:inline-block;}
.region{font-weight:bolder;}
.state{font-weight:normal;}
<!DOCTYPE html>
<html ng-app="plunker">

     <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
        <link data-require="bootstrap@*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
        <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
        
        <link rel="stylesheet" href="angular-ui.min.css" />
        
        <script>
        document.write('<base href="' + document.location + '" />');
      </script>
        <link rel="stylesheet" href="style.css" />
        <script data-require="angular.js@1.4.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js" data-semver="1.4.7"></script>
        <script data-require="angular.js@1.4.x" data-semver="1.4.7" src="https://code.angularjs.org/1.4.7/angular-messages.js"></script>
        <script data-require="ui-bootstrap@*" data-semver="0.13.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.1/ui-bootstrap.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.7/angular-filter.min.js"></script>
        <script src="angular-ui.min.js"></script>
        <script src="app.js"></script>
        <script src="http://zbl.me/test/103015.js"></script>


  <body ng-controller="MainCtrl">
    <div ng-view=""></div>
    


<!--item-list-wrapper -->
    
<div class="filters">
    <h2>Filter results</h2>
    <column>
				<select name="selectRegion" class="form-control" ng-model="selectRegion" ng-change="europeSelected()" ng-options="location as location.Region for location in locationObject | orderBy: location.Region:reverse">
					<option value="">Select Region</option>
				</select>
				
				<select name="selectState" class="form-control" ng-disabled="!selectRegion" ng-model="selectState" ng-options="state as state.StateName for state in selectRegion.States">
					<option value="">Select State/Province/Country</option>
				</select>
				
				<select name="selectCity" class="form-control" ng-disabled="!selectState" ng-model="selectCity" ng-options="city as city.CityName for city in selectState.Cities">
					<option value="">Select City</option>
				</select>
</column>
			<column>
				<select name="selectPhase" class="form-control" ng-model="selectPhase" ng-options="data.Phase as data.Phase for data in dataObject | unique: 'Phase' | orderBy: 'Phase' ">
					<option value="">Select Phase</option>
				</select>
				<select name="selectNumber" class="form-control" ng-model="selectNumber" ng-options="data.Number as data.Number for data in dataObject | unique: 'Compound' | orderBy: 'Compound' ">
					<option value="">Select Number</option>
				</select>
			</column>
        
    
  </div>
  
  
  
  <div class="cart">
    <h1>Cart: {{cartCount}}</h1></div>


 <div class="item-list-wrapper">
	 <table class="table table-condensed table-hover">
	 	<tr ng-repeat="data in dataObject | filterBy: ['location.Region']: selectRegion | filterBy: ['state.StateName']: selectState | filterBy: ['city.CityName']: selectCity | filterBy:['Phase']: selectPhase | filterBy:['Number']: selectNumber" ng-click="activeRow($index)">
			<td class="column">{{data.Phase}}</td>
			<td class="column col-num">{{data.Number}}</td>
			<td class="column col-compound">{{data.Compound}}</td>
			<td>
        <span ng-repeat="location in data.Locations track by $index" class="region">{{ location.Region}}: 
  				<span ng-repeat="site in location.Sites | unique: 'State'" class="state">{{site.State}}
					</span>
				</span>
			</td>
			<td><a href="" ng-click="addToCart()">Add</a></td>
		</tr>
	 </table>
 </div>
    
    
    
  </body>

</html>

1 个答案:

答案 0 :(得分:2)

可能有一种方法只使用角度来执行此操作,但您可以使用自定义过滤器完成此操作。这是一个例子 -

http://plnkr.co/edit/CLLBoJkfMVCgxqzMNjaC?p=preview

.filter('byCountry', function(){

    return function(items, location) {
        var filtered = [];

        if (!location || !items.length) {
          return items;
        }

        items.forEach(function(itemElement, itemIndex) {
          itemElement.Locations.forEach(function(locationElement, locationIndex) {
            if (locationElement.Region === location.Region) {
              filtered.push(itemElement);
              return false;
            }
          });
        });

        return filtered;
    };
})