angularjs filter based on matching values in nested array

允我心安 提交于 2019-12-29 09:21:52

问题


Here is my code. Please run the script to see how it works :

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

app.controller('listdata', function($scope, $http) {
var data = [{
    "name": "John",
    "queue": [{
        "number": "456",
        "status": "Unavailable"
    },
    {
        "number": "111",
        "status": "Unavailable"
    },
    {
        "number": "201",
        "status": "Paused"
    }],
    "phone": "7411173737"
},
{
    "name": "George",
    "queue": [{
        "number": "111",
        "status": "Paused"
    },
    {
        "number": "456",
        "status": "Unavailable"
    }],
    "phone": "8558855858"
},
{
    "name": "Hilary",
    "queue": [{
        "number": "456",
        "status": "Unavailable"
    }],
    "phone": "5454573737"
},
{
    "name": "Edmond",
    "queue": [{
        "number": "665",
        "status": "Unavailable"
    }],
    "phone": "7454543737"
}];
$scope.a = [];
$scope.users = [];
for(i=0;i<data.length;i++){
    for(j=0;j<data[i].queue.length;j++){
        if(data[i].queue[j].number == 111 || data[i].queue[j].number == 456){
            $scope.a.push(data[i]);
        }
    }
}
$scope.users = $scope.a;
//console.log($scope.users);
   $scope.filter111 = function (user) {
            return (user.queue.find(({number}) => number === '111'));
        }
    $scope.filter456 = function (user) {
           return (user.queue.find(({number}) => number === '456'));
        }
});

app.filter('unique', function() {
   return function(collection, keyname) {
      var output = [],
          keys = [];
      angular.forEach(collection, function(item) {
          var key = item[keyname];
          if(keys.indexOf(key) === -1) {
              keys.push(key);
              output.push(item);
          }
      });
      return output;
   };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp">

<label class="switch">
  <input type="checkbox" ng-model="queue111">111
</label>
<label class="switch">
  <input type="checkbox" ng-model="queue456">456
</label>
<label class="switch">
  <input type="checkbox" ng-true-value='"Paused"' ng-false-value='' ng-model="paused">Paused
</label>
<div class="row" ng-controller="listdata">

  <div ng-repeat="user in users|filter: queue111? filter111: ''|unique:'name'|filter: queue456? filter456: ''|filter: paused track by $index">
    <p> {{user.name}} {{user.phone}}</p>
  </div>
</div>

</div>

From the above code my data array contains objects which have the name of a user, his phone number and the calling queue he belongs to.

I have four calling queues 111,456,201 and 665 respectively.

One user can be in any number of calling queues. I have filtered the data in controller such that it only shows the users who belong to either queue 111 or queue 456 in the front end.

So from my code the user Edmond belongs to queue 665 hence his details are not displayed in the front end. The other 3 users belong to either 111, 456 or both hence their details are shown in the user panel.

Then filter 111 show's only those users who belong to queue 111. filter 456 will show only those users who belong to queue 456.

Now a user has a status for every queue. The status can be anything like Unavailable, Paused etc.

I have a filter called Paused in the front end as shown in the code and this filter is supposed to output only those user's whose status is Paused in either 111 or the 456 queue only. It should not output the user if his status is not Paused in 111 or 456.

When I click the Paused filter it displays the name John and George. This output is actually wrong because I only want to display those whose status is Paused in either 111 or 456 queue. So in the output the result for George is correct as his status is Paused in the queue 456 but for John the output is wrong as he is not paused in the queue 111 or 456. He's paused in the queue 201 and is still being displayed by the Paused filter which is not the expected output.

Expected output is it should only display data for George as he actually belongs to one of the two queues (111 or 456) and his status is paused in one of the queues (111 or 456) which I'm displaying in the frontend when I click the Paused filter. How do I do this?


回答1:


I solved the issue by creating a custom function in the controller like this :

$scope.pausedc = function (user) {
          return (user.queue.find(({number,status}) => number === '111' && status === 'Paused' || number === '456' && status === 'Paused'));
      }

and html :

<label class="switch">
  <input type="checkbox"  ng-model="paused">Paused
</label>


<div class="row" ng-controller="listdata">

  <div ng-repeat="user in users| filter:paused? pausedc: '' track by $index">
    <p> {{user.name}} {{user.phone}}</p>
  </div>
</div>


来源:https://stackoverflow.com/questions/53894075/angularjs-filter-based-on-matching-values-in-nested-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!