angular ng-repeat пропустити елемент, якщо він відповідає виразу


91

Я шукаю спосіб в основному сказати angular пропустити елемент у ng-repeat, якщо він відповідає виразу continue;

У контролері:

$scope.players = [{
    name_key:'FirstPerson', first_name:'First', last_name:'Person'
}, {
    name_key:'SecondPerson', first_name:'Second', last_name:'Person'
}]

Тепер у своєму шаблоні я хочу показати всім, що не відповідає name_key='FirstPerson'. Я зрозумів, що це повинні бути фільтри, тому я налаштував Plunkr, щоб пограти з ним, але мені не пощастило. Спроба Plunkr


Я намагаюся зрозуміти: ти хочеш показати всі предмети, але вказати, хто збігається, а хто ні? чи просто фільтрувати?
Максим Шустін,

Відповіді:


144

Як запропонував @ Maxim Shoustin , найкращим способом досягти того, що ви хочете, було б користувальницький фільтр.
Але є й інші способи, один з них полягає в тому, щоб використовувати ng-ifдирективу на одному і тому ж елементі, якби ви поставили ng-repeatдирективу (також, ось плюнкер ):

<ul>
    <li ng-repeat="player in players" ng-if="player.name_key!='FirstPerson'"></li>
</ul>

Це може представляти незначний недолік з естетичної точки зору, але має головну перевагу в тому, що ваша фільтрація може базуватися на правилі, яке не настільки жорстко пов'язане з playersмасивом, і яке може легко отримати доступ до інших даних у межах вашої програми:

  <li 
      ng-repeat="player in players" 
      ng-if="app.loggedIn && player.name != user.name"
  ></li>

Оновлення
Як зазначалося, це одне із рішень для такого роду проблем, яке може відповідати вашим потребам чи не відповідати їм.
Як зазначено в коментарях, ng-ifце директива, яка насправді означає, що вона може робити більше речей у фоновому режимі, ніж ви могли б очікувати.
Наприклад, ng-if створює нову область з батьківської :

Сфера, створена в ngIf, успадковується від батьківської області, використовуючи прототипне успадкування.

Зазвичай це не впливає на нормальну поведінку, але для запобігання несподіваним випадкам слід пам’ятати про це перед впровадженням.


це саме те, що я шукав, знав, що повинен бути якийсь короткий і солодкий спосіб зробити це без спеціального фільтра. Дякую!
aron.duby

Примітка. Існує деяка поведінка сфери застосування ng-if, яка може бути складною. Я спробував цей метод, і це спричинило проблеми в інших місцях. А саме, у мене є директива "спостерігача", яка транслює подію, коли ретранслятор закінчений. Після додавання ng-if до цього репітера він більше не запускав цю подію. Спеціальний фільтр насправді може бути найчистішим способом.
claywhipkey

@claywhipkey ти маєш рацію, найчистішим способом є використання фільтра, але це підходить не для всіх випадків. У будь-якому випадку, thx для коментаря, і ви можете бачити, що я додав оновлення heads-up у відповідь лише для того, щоб хтось усвідомив наслідки використання директиви для фільтрації даних.
gion_13

43

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

Об'єкт: Об'єкт шаблону можна використовувати для фільтрації певних властивостей об'єктів, що містяться в масиві. Наприклад, предикат {name: "M", phone: "1"} поверне масив елементів, що мають ім'я властивості, що містить "M", і телефон власності, що містить "1". ... Присудок можна заперечити, додавши до рядка префікс!. Наприклад, предикат {name: "! M"} поверне масив елементів, які мають ім'я властивості, що не містить "M".

Отже, для прикладу TS слід робити щось подібне:

<ul>
    <li ng-repeat="player in players | filter: { name_key: '!FirstPerson' }"></li>
</ul>

Не потрібно писати власні фільтри, не потрібно використовувати ng-ifз ним новий обсяг.


Просто до суті. Жоден спеціальний фільтр або новий обсяг, створений за заявою автора. Ідеально підходить для пропуску одного значення у списку.
mbokil

Я думаю, вам потрібно опустити "player" із "player.name_key" - так що у наведеному вище прикладі це просто "{name_key: '! FirstPerson'}".
smithml

Я ніколи не зміг змусити Angular грати приємно з порожніми клавішами. Чи існує якась хитрість у використанні вбудованих фільтрів для еквівалента player in players | filter: { name_key: '' }? Ця конкретна директива не буде відповідати лише гравцям, які не мають порожнього місця name_key. Інверсія, name_key: '!'призначена для вибору будь-якого гравця з непустим, name_keyтакож не буде працювати.
Ерік Л.

Ви можете перевірити цю відповідь.
Ілля Лузянин

4
Пам'ятайте, що це працює лише з масивами, а не з властивостями об'єктів у такому випадку, якng-repeat="(key, val) in player"
David Diez

19

Ви можете використовувати власний фільтр під час реалізації ng-repeat. Щось на зразок:

 data-ng-repeat="player in players |  myfilter:search.name

myfilter.js:

app.filter('myfilter', function() {


   return function( items, name) {
    var filtered = [];

    angular.forEach(items, function(item) {

      if(name == undefined || name == ''){
        filtered.push(item);
        }

      /* only if you want start With*/
      // else if(item.name_key.substring(0, name.length) !== name){
      //   filtered.push(item);
      // }

      /* if you want contains*/
      // else if(item.name_key.indexOf(name) < 0 ){
      //   filtered.push(item);
      // }

       /* if you want match full name*/
       else if(item.name_key !== name ){
        filtered.push(item);
      }
    });

    return filtered;
  };
});

Демо Plunker


Дякую за працю, яку ви доклали до цього. Це точно, але в підсумку я пішов із легкістю відповіді @ gion_13 у коді, тому вирішив, що краще позначити його як прийняту відповідь
aron.duby
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.