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小组讨论:groups.google.com/d/topic/angular/wR06cN5oVBQ/discussion
Mark Rajcok 2012年

Answers:


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,您将如何处理?
Dani 2013年

5
nh-show在我的情况下有效,但是当我放入过滤器却没有返回任何内容时,它不会更新状态。同样,对象在第一次加载时出现,并在页面加载时完成重复过程时消失。
dvdmn

1
@Dani尝试将一个函数添加到执行测试的控制器中。然后,您可以使用调用指令ng-hide="hasEvents()"
S先生

对了谢谢。但是,我希望有一种更优雅的方式而不会“污染”控制器。
Dani 2013年

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 2013年

7
@MKSafi,它将在调用的作用域上创建一个新变量,filteredItems并将其值设置为(items | filter:keyword)-换句话说,过滤器返回的数组
AlexFoxGill 2014年

17
是!忍者加分!这样可以避免两次评估复杂的滤波器而节省角度!
markmarijnissen 2014年

2
此外,使用多个过滤器似乎对此有一些限制,例如"face in filteredFaces = faces|filter:{deleted: true} | orderBy:'text'但我同意所有人的意见,这是一个绝妙的技巧。
Fitter Man

29

如果您只想在列表为空时从DOM中删除,则可能要签出angular-ui指令ui-iful

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

1
谢谢。感觉不仅仅是将其隐藏起来。
Prinzhorn

@Mortimer:那么在这种情况下我们需要angular-ui吗?
Shibbir Ahmed

您可以在ng-hide不使用angular-ui的情况下使用,但它只会隐藏节点,不会将其从DOM树中删除。使用angular-ui的ui-if指令,它将删除DOM节点。因此,您至少需要将ui-if指令从angular-ui代码添加到您自己的代码中。
Mortimer

21
最新的角度ng-if包括!
markmarijnissen 2014年

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 2015年

如何使用多个过滤器?
约达什

@Jordash保持顺畅item in items | filter: ... | filter: ...
Bernard

一个不错的,进一步的改进是<li ng-if="!filteredItems.length">
Matty J

这很棒。像item in (filteredItems = (items | filter: someFilter))
Firze

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 =“ itemfilteredItems”>等将被注释掉,并成为注释而不是li元素。


问题说:“我希望在列表所在的位置有一个消息框”。我也认为将逻辑分成样式表是不利的。难以维护和麻烦。
Prinzhorn'1

1
@Prinzhorn,我认为使用CSS是一个优势,因为逻辑非常简单且易于维护,CSS可重用于其他列表,并且不依赖JavaScript。不需要其他的听众或观察者。消息的样式可以看起来像一个盒子,我只是没有简单地回答。
米里亚姆·萨尔泽

延迟了几个月,理所当然,但我同意Miriam,我认为这个答案是个天才。
乔恩·科姆

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

您可以使用ng-if,因为它不是在html页面中呈现的,并且您不会在inspect中看到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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.