Як я фільтрую масив з AngularJS і використовую властивість відфільтрованого об'єкта як атрибут ng-model?


122

Якщо у мене є масив об'єктів і я хочу прив’язати модель Angular до властивості одного з елементів на основі фільтра, як це зробити? Я можу пояснити краще на конкретному прикладі:

HTML:

<!DOCTYPE html>
<html ng-app>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
        <meta charset=utf-8 />
        <title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
        <input ng-model="results.year">
        <input ng-model="results.subjects.title | filter:{grade:'C'}">
    </body>
</html>

Контролер:

function MyCtrl($scope) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
}

JSBin: http://jsbin.com/adisax/1/edit

Я хочу відфільтрувати другий вхід до теми оцінкою "C", але я не хочу прив'язувати модель до класу ; Я хочу прив’язати його до назви предмета, який має оцінку "С".

Чи можливо це, і якщо так, то як це робиться?

Відповіді:


127
<div ng-repeat="subject in results.subjects | filter:{grade:'C'}">
    <input ng-model="subject.title" />
</div>

1
Я бачу, куди ви їдете з цим, але мені дуже не хотілося повторювача. Властивість, за якою я фактично фільтрую, - це стовпчик ідентичності, тому він унікальний. Але я бачу, що це був би правильний спосіб вирішити загальну проблему.
— Бернхард Хофманн

1
це підручник для італійських людей :) dev.stasbranger.com/post/77190983049/…
— Сільвіо Троя

10
це було дуже корисно, а для зворотного (все, крім C), це спрацювало б:filter:{grade:'!'+'C'}
— pulkitsinghal

2
Ви можете зробити те ж саме з a grade array? У моєму випадку я будую свій масив класів з виду дерева та хочу фільтрувати результат для тих, хто в масиві.
— Хуан Карлос Оропеза

157

Ви можете використовувати фільтр "фільтр" у своєму контролері, щоб отримати всі оцінки "С". Отримання першого елемента масиву результатів дасть вам назву предмета, який має ступінь "C".

$scope.gradeC = $filter('filter')($scope.results.subjects, {grade: 'C'})[0];

http://jsbin.com/ewitun/1/edit

Те саме з звичайним ES6:

$scope.gradeC = $scope.results.subjects.filter((subject) => subject.grade === 'C')[0]

мені шкода, що я не слідкую за тим другим фільтром ("фільтром"), чи можете ви пояснити цей ще трохи?
— Winnemucca

1
@stevek Ось назва фільтра. Метод filter () дає вам фільтр. Просто фільтр називається filter, оскільки він фільтрує масив. Це виглядатиме так з фільтром валют: $ filter ('валюта') (сума, символ, дріб) Розмірити
— Олівер


13

зверніть увагу, якщо ви використовуєте $ filter так:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

і у вас трапився ще один клас для, О, я не знаю, CC або AC або C + або CCC це втягує їх у. вам потрібно додати вимогу для точної відповідності:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'}, true);

Це дійсно вбило мене, коли я втягував такі деталі комісії, як ця:

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}))[0];

зателефонували лише за помилку, оскільки вона втягнула в комісію ID 56, а не 6.

Додавання справжніх сил точно збігається.

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}, true))[0];

Але все ж я віддаю перевагу цьому (я використовую машинопис, звідси "Нехай" і =>):

let obj = this.$filter('filter')(this.CommissionTypes, (item) =>{ 
             return item.commission_type_id === 6;
           })[0];

Я це роблю, тому що, в якийсь момент вниз по дорозі, я, можливо, захочу отримати додаткову інформацію з цих відфільтрованих даних тощо.


У мене була така ж помилка, як і у вас, дякую за підказку з третім булевим параметром. Не знав про це.
— Георг Лебер

12

якщо ви хочете створити окремий список результатів у контролері, ви можете застосувати фільтр

function MyCtrl($scope, filterFilter) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
  //create a filtered array of results 
  //with grade 'C' or subjects that have been failed
  $scope.failedSubjects = filterFilter($scope.results.subjects, {'grade':'C'});
}

Тоді ви можете посилатися на пошкоджені суб'єкти так само, як і в результатах об'єкт

більше про це можна прочитати тут https://docs.angularjs.org/guide/filter

оскільки ця відповідь під кутом оновила документацію, вони тепер рекомендують викликати фільтр

// update 
// eg: $filter('filter')(array, expression, comparator, anyPropertyKey);
// becomes
$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

що таке filterFilter? це якась послуга чи директива? де код для filterFilter?
— Mou

це кутове обслуговування. Подивіться перший приклад за посиланням вище. (В файлі scripts.js)
— Кіран

хоча вони змінили документацію filterFilter все ще працює ..
— Kieran

4

Ви також можете використовувати функції з $filter('filter'):

var foo = $filter('filter')($scope.results.subjects, function (item) {
  return item.grade !== 'A';
});

4

Якщо ви використовуєте ES6, ви можете:

var sample = [1, 2, 3]

var result = sample.filter(elem => elem !== 2)

/* output */
[1, 3]

Також фільтр зауваження не оновлює існуючий масив, він щоразу повертає новий відфільтрований масив.


0

Застосовуючи той же фільтр у HTML із кількома стовпцями, лише приклад:

 variable = (array | filter : {Lookup1Id : subject.Lookup1Id, Lookup2Id : subject.Lookup2Id} : true)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.