Как мне отфильтровать массив с помощью 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
Я понимаю, к чему вы клоните, но мне действительно не нужен репитер. Свойство, по которому я буду фильтровать, - это столбец идентификаторов, поэтому он уникален. Но я вижу, что это был бы правильный способ решения общей проблемы.
— Bernhard Hofmann

1
это учебник для итальянцев
— Сильвио Троя

10
это было очень полезно, и для инверсии (все, кроме C) это сработает:filter:{grade:'!'+'C'}
— pulkitsinghal

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

157

Вы можете использовать фильтр «фильтр» в вашем контроллере, чтобы получить все оценки «C». Получение первого элемента массива результатов даст вам название предмета с оценкой «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 ('currency') (amount, symbol, FractionSize) Проверьте документы здесь: docs.angularjs.org/api/ng/filter
— Оливер,

61

Вот модифицированный JSBin с рабочим образцом:

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

Вот что я сделал с фильтрами на входе:

<input ng-model="(results.subjects | filter:{grade:'C'})[0].title">

1
Это реальная сделка. Это сила. Это способ. Я пошел с этим и теперь счастлив.
— user1576978

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];

вызвали только за ошибку, потому что она вытаскивала идентификатор комиссии 56, а не 6.

Добавление истинных сил точного совпадения.

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

Тем не менее, я предпочитаю это (я использую машинописный текст, отсюда «Let» и =>):

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'});
}

Затем вы можете ссылаться на failedSubjects так же, как и на объект результатов.

вы можете прочитать об этом здесь https://docs.angularjs.org/guide/filter

поскольку этот ответ angular обновил документацию, теперь они рекомендуют вызывать фильтр

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

что такое filterFilter? это какая-то услуга или директива? где код для filterFilter?
— Mou

это угловой сервис. Взгляните на первый пример по ссылке выше. (в файле scripts.js)
— Киран

хотя они изменили документацию filter Filter все еще работает ..
— Киран

5

Если вы используете ES6, вы можете:

var sample = [1, 2, 3]

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

/* output */
[1, 3]

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


4

Вы также можете использовать функции с $filter('filter'):

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

0

Применение того же фильтра в HTML с несколькими столбцами, просто пример:

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