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の試み


私は理解しようとします:すべてのアイテムを表示しますか?または単にフィルター?
Maxim Shoustin 2013年

回答:


144

以下のよう@Maxim Shoustinが提案し、あなたが望むものを達成するための最良の方法は、カスタムフィルタを使用することです。
しかし、他の方法もあります。それらの1つは、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>

更新
前述のように、これはこの種の問題に対する解決策の1つであり、ニーズに合う場合とそうでない場合があります。
コメントで指摘されているように、ng-ifはディレクティブです。これは、実際には、バックグラウンドで予想よりも多くのことを行う可能性があることを意味します。
たとえば、そのng-if 親から新しいスコープを作成します

ngIf内で作成されたスコープは、プロトタイプ継承を使用して親スコープから継承します。

通常、これは通常の動作には影響しませんが、予期しないケースを防ぐために、実装する前にこれを覚えておく必要があります。


これはまさに私が探していたものでした。カスタムフィルターなしでそれを行うには、短くて甘い方法が必要だと知っていました。ありがとう!
aron.duby 2013年

注:扱いにくいng-ifのスコープ動作がいくつかあります。私はこの方法を試しましたが、他の場所で問題が発生しました。つまり、リピーターが終了したときにイベントをブロードキャストする「ウォッチャー」ディレクティブがあります。このリピーターにng-ifを追加すると、そのイベントは発生しなくなりました。カスタムフィルターは、実際には最もクリーンな方法です。
クレイウイスキー

@claywhipkeyあなたが正しい、最もクリーンな方法はフィルターを使用することですが、それはすべてのケースに適しているわけではありません。とにかく、コメントのthxと、データをフィルターするためのディレクティブを使用することの影響を誰かに知らせるために、ヘッズアップの更新を回答に追加したことがわかります。
gion_13

43

私はこれが古いものであることを知っていますが、誰かが別の可能な解決策を探す場合、これを解決する別の方法があります-標準のフィルター機能を使用します:

オブジェクト:パターンオブジェクトを使用して、配列に含まれるオブジェクトの特定のプロパティをフィルタリングできます。たとえば、{name: "M"、phone: "1"}述語は、 "M"を含むプロパティ名と "1"を含むプロパティphoneを持つアイテムの配列を返します。... 文字列の前に!を付けると、述語を否定できます。たとえば、{name: "!M"}述語は、 "M"を含まないプロパティ名を持つアイテムの配列を返します。

したがって、TSの例では、次のようなことを行う必要があります。

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

カスタムフィルターを記述する必要はなく、ng-if新しいスコープで使用する必要もありません。


要点は簡単です。作成者が述べたように、カスタムフィルターや新しいスコープは作成されません。リスト内の単一の値をスキップするのに最適です。
mbokil

「player.name_key」から「player」を省略する必要があると思います。つまり、上の例では「{name_key: '!FirstPerson'}」になります。
smithml 2015

空のキーでAngularをうまくプレイすることはできませんでした。同等の組み込みフィルターを使用するための何らかのトリックはありplayer in players | filter: { name_key: '' }ますか?この特定のディレクティブは、を持たない/空のプレイヤーのみに一致しませんname_keyname_key: '!'name_keyではないプレイヤーを選択するための逆も、機能しません。
エリックL.

この答えを確認できます。
Ilya Luzyanin 2015

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.