简体   繁体   English

AngularJS:使用多级JSON进行过滤和唯一性

[英]AngularJS: Filtering and Uniques with multi level JSON

I have a dataset that is displayed in a table. 我有一个显示在表中的数据集。 Each object has a child object of Locations, that also have a child object of Region and Sites, which is an array. 每个对象都有一个Locations的子对象,也有Region和Sites的子对象,后者是一个数组。

I'm having trouble with 2 issues: 我遇到2个问题:

First, in my view to display the Sites data (which is the 'State' value), I'm getting duplicates. 首先,我认为要显示“网站”数据(即“州”值),我会得到重复数据。 I'm trying to use the 'unique' filter to show only unique State values, but it's not working. 我正在尝试使用“唯一”过滤器来仅显示唯一的State值,但是它不起作用。

Second, I'm wanting to use the select lists with these data elements of Region, State/Country/Province and City to act as a filtering mechanism. 其次,我想将选择列表与Region,State / Country / Province和City的这些数据元素一起使用,以充当过滤机制。 That's not working either. 那也不行。

See Plunkr for working example: http://plnkr.co/edit/p0ImqB?p=preview 有关工作示例,请参见Plunkr: http ://plnkr.co/edit/p0ImqB?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:300px;clear:both;margin-left:20px;} .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> </head> <body ng-controller="MainCtrl"> <div ng-view=""></div> <div class="filters"> <h2>Filter results</h2> <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> </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" ng-click="activeRow($index)"> <td class="column">{{data.Phase}}</td> <td class="column col-num">{{data.Number}}</td> <td class="column col-compound">{{data.Item}}</td> <td> <span ng-repeat="location in data.Locations track by $index" class="region">{{ location.Region}}: <span ng-repeat="sites in location.Sites track by $index" class="state"> <span ng-repeat="item in sites.State track by $index | unique: 'item' ">{{item}}</span> </span> </span> </td> <td><a href="" ng-click="addToCart()">Add</a></td> </tr> </table> </div> </body> </html> 

The problem is in the HTML, you were repeating in sites.State but there is not any array there, it's only a string. 问题出在HTML中,您在sites.State中重复,但是那里没有任何数组,它只是一个字符串。

Changing the item-list-wrapper to this one in the HTML will solve the problem: 在HTML中将item-list-wrapper更改为此选项将解决此问题:

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

Here´s the plunker: http://plnkr.co/edit/VmLjZmgLtDuds5CM7lKM?p=preview 这是the客: http ://plnkr.co/edit/VmLjZmgLtDuds5CM7lKM?p=preview

Regarding the second problem with the filters, I'd solve it with the following custom filters: 关于过滤器的第二个问题,我将使用以下自定义过滤器解决:

app.filter('itemFilter', function() {
 return function(input,region,state) {
    if (!region)
      return input;
    return input.filter(function (x) {
      return x.Locations.some(function (y) {
        if (!state)
          return y.Region == region.Region;
        else
          return y.Sites.some(function (z) {
            return z.State == state.StateName;
          });
      });
    });
  };
});

app.filter('regionFilter', function() {
  return function(input,region,state) {
    if (!region)
      return input;
    return input.filter(function(y) {
      if (!state)
        return y.Region == region.Region;
      else
        return y.Sites.some(function (z) {
          return z.State == state.StateName;
        });
    });
  };
});

You can use them in the code as shown below: 您可以在如下所示的代码中使用它们:

 <div class="item-list-wrapper">
     <table class="table table-condensed table-hover">
        <tr ng-repeat="data in dataObject | itemFilter:selectRegion:selectState" 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 | regionFilter:selectRegion:selectState" class="region">{{ location.Region}}: 
                <span ng-repeat="site in location.Sites | unique: 'State' | filter: { State: selectState.StateName }" class="state">{{site.State}}
                    </span>
                </span>
            </td>
            <td><a href="" ng-click="addToCart()">Add</a></td>
        </tr>
     </table>
 </div>

Here's the plunker: http://plnkr.co/edit/liWYtMIC1rDktmBYQtjo?p=preview 这是the客: http ://plnkr.co/edit/liWYtMIC1rDktmBYQtjo?p=preview

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM