Как отфильтровать родительский объект, зациклив его дочерний массив объекта

Я получаю некоторые объекты из бэкэнда. каждый объект имеет дочерний массив с именем «phaseIds», он имеет несколько массивов объектов, из массива, который мне требуется, чтобы найти существование «имени» в соответствии с фильтром.

после того, как я отфильтровал, этот объект должен отображаться на странице. Я пытался, но я не могу получить результат. кто-нибудь поможет мне с правильным способом сделать это?

в настоящее время меня фильтруют студенты, но я получаю все объекты без фильтрации.

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

var projects = [
    {"name":"one", "PhaseIds":[
      {id:"1",name:"school"},
      {id:"2",name:"student"},
      {id:"3",name:"teacher"}
      ]},
      {"name":"two", "PhaseIds":[
      {id:"1",name:"school"},
      {id:"3",name:"teacher"}
      ]},
      {"name":"three", "PhaseIds":[
      {id:"1",name:"school"},
      {id:"2",name:"student"}
      ]},
      {"name":"four", "PhaseIds":[
      {id:"1",name:"school"},
      {id:"3",name:"teacher"}
      ]},
      {"name":"five", "PhaseIds":[
      {id:"1",name:"school"},
      {id:"3",name:"teacher"}
      ]}
  ]

app.controller('MainCtrl', function($scope) {
  
  $scope.projects = angular.forEach( projects, function (project) {
    
   var filteredProject = project;
   
   angular.forEach( project.PhaseIds, function ( phase ) {
     
    if(phase.name.toLowerCase().indexOf('student') > -1 ){ 
      //only required the students avilable projects
      
        return filteredProject;
      
    }
      
   })
    
  })
  
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainCtrl">
<ul>
      <li ng-repeat="project in projects">{{project.name}}</li>
</ul>
  </div>

Демонстрация в реальном времени


person user2024080    schedule 04.09.2015    source источник


Ответы (4)


Вам не нужно помещать логику в код вашего контроллера. Вы также можете добиться этого в своем фрагменте HTML, используя $filter. Проверьте приведенный ниже пример. Вы можете сделать структуру фильтра настолько глубокой, насколько захотите.

<ul>
  <li ng-repeat="project in projects | filter:{ PhaseIds : { name : 'student' } }">{{project.name}}</li>
</ul>

Проверьте свой планкер. я обновил его

person Vineet    schedule 04.09.2015
comment
для статической цели может быть эта работа. но я ищу динамическое обновление. в моем случае нет кнопок для каждого «ученика», «учителя», например.. в зависимости от щелчка пользователя (кнопка фильтра) мне нужно показать разные проекты - person user2024080; 04.09.2015
comment
Вы можете добиться того же в приведенном выше фрагменте :-) - person Vineet; 04.09.2015
comment
Привет, vineet, я попробовал ваше решение. У меня, когда я пробовал в JSFIDDLE, это не сработало, не могли бы вы проверить, что я делаю неправильно.. Ссылка: jsfiddle.net/varun1989/w9qyqjz7/1 - person Varun; 04.09.2015

Я предпочитаю решение @Vineet, но если вам нужно поиграть с Json с контроллера, правильный код должен быть:

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

    $scope.projects = [];
    angular.forEach(projects, function (project) {

        var filteredProject = project;

        angular.forEach(project.PhaseIds, function (phase) {
            if (phase.name.toLowerCase().indexOf('student') > -1) {
                //only required the students avilable projects
                $scope.projects.push(filteredProject);
            }
        })
    })
});
person michelem    schedule 04.09.2015

Вы можете увидеть решение здесь - http://plnkr.co/edit/seIfZlhIbUnYMhWdEpGr

var filterProjectData = function(projects) {

   var filteredProjects = []; 

  angular.forEach( projects, function (project) {

   angular.forEach( project.PhaseIds, function ( phase ) {

    if(phase.name.toLowerCase().indexOf('student') > -1 ){ 
      //only required the students avilable projects

        filteredProjects.push(project);
    }

   });

  });

  return filteredProjects;
}

$scope.projects = filterProjectData(projects);

Без мозгов. Я просто подправил вашу логику foreach.

person Rabi    schedule 04.09.2015

Попробуй это

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

  $scope.projects = [];
  angular.forEach( projects, function (project) {

   var filteredProject = project;

   angular.forEach( project.PhaseIds, function ( phase ) {

    if(phase.name.toLowerCase().indexOf('student') > -1 ){ 
      //only required the students avilable projects

       $scope.projects = $scope.projects.concat(filteredProject)    
    }

   })

  })

});

Это плункер

РЕДАКТИРОВАТЬ :

используя concat, вы получите структуру объекта, подобную этой, в соответствии с вашими требованиями.

[   {"name":"one", "PhaseIds":[
      {id:"1",name:"school"},
      {id:"2",name:"student"},
      {id:"3",name:"teacher"}
      ]},

      {"name":"three", "PhaseIds":[
      {id:"1",name:"school"},
      {id:"2",name:"student"}
      ]}       
  ]

И с помощью push вы получите вот так

[0: [{
    "name": "one",
    "PhaseIds": [{
        id: "1",
        name: "school"
    },
    {
        id: "2",
        name: "student"
    },
    {
        id: "3",
        name: "teacher"
    }]
}],
1: [{
    "name": "three",
    "PhaseIds": [{
        id: "1",
        name: "school"
    },
    {
        id: "2",
        name: "student"
    }]
}]]
person RIYAJ KHAN    schedule 04.09.2015
comment
почему concat вместо push - какая-то особая причина? - person user2024080; 04.09.2015