AngularJS ng-repeatハンドルの空リストのケース


377

これは非常に一般的なことだと思いましたが、AngularJSでそれを処理する方法を見つけることができませんでした。イベントのリストがあり、AngularJSでそれらを出力したい場合、それは非常に簡単です。

<ul>
    <li ng-repeat="event in events">{{event.title}}</li>
</ul>

しかし、リストが空の場合はどうすればよいですか?リストに「イベントなし」などが表示される場所にメッセージボックスを配置したいのですが。接近するのはng-switchwith events.lengthだけです(配列ではなくオブジェクトのときに空かどうかを確認するにはどうすればよいですか?)。


4
@Artemの答えは良い(+1)です。参照/比較のためにフィルターを使用するGoogleグループディスカッションは次のとおり
Mark Rajcok

回答:


569

ngShowを使用できます。

<li ng-show="!events.length">No events</li>

例を参照してください。

または、ngHideを使用できます

<li ng-hide="events.length">No events</li>

例を参照してください。

オブジェクトの場合、Object.keysをテストできます。


1
確かに@ArtemAndreev。「イベント」が空の配列の場合、配列が空であってもtrueを返します
Rob Juurlink

Object.keysに問題があると思います:jsfiddle.net/J9b5z、これをどのように処理しますか?
ダニジュン

5
nh-showは私のケースで機能しましたが、フィルターを挿入しても何も返されない場合、状態は更新されません。また、オブジェクトは最初のロードで表示され、ページのロードで繰り返されるプロセスが完了すると消えます。
dvdmn 2013年

1
@Daniは、テストを実行する関数をコントローラーに追加してみます。次に、でディレクティブを呼び出すだけng-hide="hasEvents()"です。
S氏

はい、ありがとう。ただし、コントローラーを「汚染」しない、より洗練された方法があることを望みました。
ダニ

370

そして、これをフィルタリングされたリストで使用したい場合は、ここに巧妙なトリックがあります:

<ul>
    <li ng-repeat="item in filteredItems  = (items | filter:keyword)">
        ...
    </li>
</ul>
<div ng-hide="filteredItems.length">No items found</div>

3
非常に便利。「filteredFragments」を使用したタイプミス。
ravishi 2013

1
甘い!ng-repeat内の表現は奇妙に見えます。あなたはそれを説明できますか?ありがとう!!
MK Safi

7
@MKSafi、それは呼び出されたスコープで新しい変数を作成し、filteredItemsその値を設定します(items | filter:keyword)-言い換えると、フィルターによって返される配列
AlexFoxGill

17
はい!忍者プラスポイント!これにより、複雑なフィルターを2回評価することによる角度を節約できます。
markmarijnissen 14年

2
また、複数のフィルターを使用する場合、これにはいくつかの制限があるようです"face in filteredFaces = faces|filter:{deleted: true} | orderBy:'text'が、私は皆に同意しますが、これは素晴らしいトリックです。
Fitter Man

29

リストが空のときにDOMからを削除するだけの場合は、angular-uiディレクティブ をチェックアウトするui-ifことをお勧めしulます。

<ul ui-if="!!events.length">
    <li ng-repeat="event in events">{{event.title}}</li>
</ul>

1
ありがとう。単に隠すよりもきれいに感じます。
Prinzhorn、

@Mortimer:この場合、angular-uiが必要ですか?
Shibbir Ahmed 2013

ng-hideangular-uiがなくても使用できますが、ノードを非表示にするだけで、DOMツリーからは削除されません。angular-uiのui-ifディレクティブを使用すると、DOMノードが削除されます。したがって、少なくともui-if自分自身のコードにangular-uiコードからディレクティブを追加する必要があります。
Mortimer 2013年

21
最新の角度がng-if含まれています!
markmarijnissen 14年

4
ng-ifが新しいスコープを作成していることに注意してくださいng-hide。これにより、予期しない動作が発生する可能性があります。
アーノルドダニエルズ

29

angularjsの新しいバージョンでは、この質問に対する正しい答えは次のようにすることng-ifです:

<ul>
  <li ng-if="list.length === 0">( No items in this list yet! )</li>
  <li ng-repeat="item in list">{{ item }}</li>
</ul>

メッセージを表示するにはリストを定義し、長さを0にする必要があるため、リストがダウンロードされようとしているときにも、このソリューションはちらつきません。

ここにそれを使用していることを示すためのプランカーがあります:http ://plnkr.co/edit/in7ha1wTlpuVgamiOblS?p=preview

ヒント:ロード中のテキストまたはスピナーを表示することもできます。

  <li ng-if="!list">( Loading... )</li>

23
<ul>
    <li ng-repeat="item in items | filter:keyword as filteredItems">
        ...
    </li>
    <li ng-if="filteredItems.length===0">
        No items found
    </li>
</ul>

これは@Konradの「ktoso」Malawskiに似ていますが、覚えやすくなっています。

Angular 1.4でテスト済み


3
あなたの平均ng-if='!filteredItems.length'
abrunet

複数のフィルターでこれをどのように行いますか?
ジョーダッシュ、2016年

@Jordashただパイプを張っているだけ item in items | filter: ... | filter: ...
Bernard

さらに洗練されたものに<li ng-if="!filteredItems.length">
Matty J

これは素晴らしい。私は以前よりずっと汚い方法を使ってきましたitem in (filteredItems = (items | filter: someFilter))
Firze

6

JavaScript / AngularJSの代わりにCSSを使用する別のアプローチを次に示します。

CSS:

.emptymsg {
  display: list-item;
}

li + .emptymsg {
  display: none;
}

マークアップ:

<ul>
    <li ng-repeat="item in filteredItems"> ... </li>
    <li class="emptymsg">No items found</li>
</ul>

リストが空の場合、<li ng-repeat = "item in filteredItems">などはコメント化され、li要素ではなくコメントになります。


「リストがある場所にメッセージボックスを配置したい」という質問です。ロジックをスタイルシートに分離することも不利だと思います。メンテナンスが難しく、トラブルを招く。
Prinzhorn 2016年

1
@ Prinzhorn、CSSを使用することの利点は、ロジックが非常にシンプルで維持しやすく、CSSが他のリストで再利用可能で、JavaScriptに依存しないためです。追加のリスナーやウォッチャーは必要ありません。メッセージはボックスのように見えるようにスタイルを整えることができますが、私は答えを単純にしたくありませんでした。
ミリアムサルツァー2016年

数ヶ月遅れて当然ですが、ミリアムに同意します。この答えは天才だと思います。
Jon Combe 2016年

2

このng-switchを使用できます。

<div ng-app ng-controller="friendsCtrl">
  <label>Search: </label><input ng-model="searchText" type="text">
  <div ng-init="filtered = (friends | filter:searchText)">
  <h3>'Found '{{(friends | filter:searchText).length}} friends</h3>
  <div ng-switch="(friends | filter:searchText).length">
    <span class="ng-empty" ng-switch-when="0">No friends</span>
    <table ng-switch-default>
      <thead>  
        <tr>
          <th>Name</th>
          <th>Phone</th>
        </tr>
      </thead>
      <tbody>
      <tr ng-repeat="friend in friends | filter:searchText">
        <td>{{friend.name}}</td>
        <td>{{friend.phone}}</td>
      </tr>
    </tbody>
  </table>
</div>

1

asキーワードを使用して、ng-repeat要素の下のコレクションを参照できます。

<table>
    <tr ng-repeat="task in tasks | filter:category | filter:query as res">
        <td>{{task.id}}</td>
        <td>{{task.description}}</td>
    </tr>
    <tr ng-if="res.length === 0">
        <td colspan="2">no results</td>
    </tr>
</table>

0

私は通常ng-showを使用します

<li ng-show="variable.length"></li>

たとえば、変数を定義する場合

<div class="list-group-item" ng-repeat="product in store.products">
   <li ng-show="product.length">show something</li>
</div>

0

これはhtmlページにレンダリングされないため、ng-ifを使用でき、検査でhtmlタグが表示されません...

<ul ng-repeat="item in items" ng-if="items.length > 0">
    <li>{{item}}<li>
</ul>
<div class="alert alert-info">there is no items!</div>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.