AngularJS of-repeat обрабатывает пустой список

343

Я думал, что это будет очень распространенная вещь, но я не мог найти, как обращаться с ней в AngularJS. Скажем, у меня есть список событий и хочу вывести их с помощью AngularJS, тогда это довольно легко:

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

Но как мне обрабатывать случай, когда список пуст? Я хочу иметь окно с сообщениями, где в списке есть что-то вроде "Нет событий" или подобных. Единственное, что подошло бы близко, это ng-switch с events.length (как проверить, пусто ли, когда объект, а не массив?), Но это действительно единственный вариант, который у меня есть?

  • 4
    @ Артем ответил хорошо (+1). Вот обсуждение группы Google, которое использует фильтр, для справки / сравнения: groups.google.com/d/topic/angular/wR06cN5oVBQ/discussion
Теги:
angularjs-ng-repeat
angularjs-ng-show

9 ответов

542
Лучший ответ

Вы можете использовать ngShow.

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

См. пример.

Или вы можете использовать ngHide

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

См. пример.

Для объекта вы можете протестировать Object.keys.

  • 1
    @shibbir Это проверка, определены ли события. См. Jsfiddle.net/BXRPE .
  • 1
    Действительно @ArtemAndreev. Когда «events» является пустым массивом, он возвращает true, даже если массив пуст
Показать ещё 6 комментариев
348

И если вы хотите использовать это с отфильтрованным списком здесь, аккуратный трюк:

<ul>
    <li ng-repeat="item in filteredItems  = (items | filter:keyword)">
        ...
    </li>
</ul>
<div ng-hide="filteredItems.length">No items found</div>
  • 3
    Очень полезно. Опечатка, хотя с "отфильтрованных фрагментов".
  • 1
    спасибо, исправил опечатку.
Показать ещё 7 комментариев
29

Возможно, вы захотите проверить angular -ui директиву ui-if, если вы просто хотите удалить ul из DOM, когда список пуст:

<ul ui-if="!!events.length">
    <li ng-repeat="event in events">{{event.title}}</li>
</ul>
  • 1
    Благодарю. Чувствует себя чище, чем просто скрывать это.
  • 0
    @ Мортимер: так в этом случае нам нужен Angular-UI?
Показать ещё 3 комментария
26

С более новыми версиями 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>
20
<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'
  • 0
    да. Я исправил код
Показать ещё 4 комментария
6

Здесь используется другой подход, использующий CSS вместо JavaScript/AngularJS.

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 filtersItems" > и т.д., будет прокомментирован и станет комментарием вместо элемента li.

  • 0
    Вопрос говорит: «Я хочу, чтобы окно сообщений было в том месте, где находится список». Я также думаю, что невыгодно разделять логику на таблицу стилей s. Трудно поддерживать и напрашиваться на неприятности.
  • 1
    @Prinzhorn, я думаю, что использование CSS является преимуществом, потому что логика очень проста и легка в обслуживании, CSS многократно используется для других списков и не зависит от JavaScript. Никаких дополнительных слушателей или наблюдателей не требуется. Сообщение может быть оформлено так, чтобы оно выглядело как коробка, я просто не хотел, чтобы ответ был простым.
Показать ещё 1 комментарий
1

Вы можете использовать этот ng-переключатель:

<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>
0

вы можете использовать ng-if, потому что это не отображается на странице html, и вы не видите свой тег 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>
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>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню