如何检查Observable数组的长度

153

在我的Angular 2组件中,我有一个可观察的数组

list$: Observable<any[]>;

在我的模板中,我有

<div *ngIf="list$.length==0">No records found.</div>

<div *ngIf="list$.length>0">
    <ul>
        <li *ngFor="let item of list$ | async">item.name</li>
    </ul>
</div>

但在Observable数组的情况下,list$.length无法工作。

更新:

看起来(list$ | async)?. length给了我们长度,但以下代码仍然无法正常工作:

<div>
    Length: {{(list$ | async)?.length}}
    <div *ngIf="(list$ | async)?.length>0">
        <ul>
            <li *ngFor="let item of (list$ | async)">
                {{item.firstName}}
            </li>
        </ul>
    </div>
</div>

有人可以指导我如何检查可观察数组的长度吗?


报告在 https://github.com/angular/angular/issues/9641 - Günter Zöchbauer
3
你在这里的方法还有一个主要问题:通过在模板中反复使用异步管道,你实际上启动了多次对单个Observable的订阅。KAMRUL HASAN SHAHED在上面提到了正确的方法:只使用一次异步管道,然后为结果提供一个别名,在子节点中可以利用该别名。 - Harry Beckwith
8个回答

275
你可以使用| async管道:
<div *ngIf="(list$ | async)?.length==0">No records found.</div>

更新 - 2021-2-17

<ul *ngIf="(list$| async) as list; else loading">
   <li *ngFor="let listItem of list">
      {{ listItem.text }}
   </li>
</ul>

<ng-template #loading>
  <p>Shows when no data, waiting for Api</p>
  <loading-component></loading-component>
</ng-template>

更新 - Angular 版本 6:

如果您正在加载 css Skeleton,可以使用此方法。如果数组没有项目,则将显示 css 模板。如果有数据,则填写 ngFor

<ul *ngIf="(list$| async)?.length > 0; else loading">
   <li *ngFor="let listItem of list$| async">
      {{ listItem.text }}
   </li>
</ul>

<ng-template #loading>
  <p>Shows when no data, waiting for Api</p>
  <loading-component></loading-component>
</ng-template>

6
我也尝试了那个方法,但是报错了:“TypeError: Cannot read property 'length' of null”。 - Naveed Ahmed
4
从您提供的信息很难确定。尝试使用<div *ngIf="(list$ | async)?.length==0">No records found.</div>(添加了?)。 - Günter Zöchbauer
7
我尝试过这个方法,它有效:<div *ngIf="(list$ | async)?.length==0">未找到记录。</div> - Naveed Ahmed
5
需要额外的 ? 是因为 list$ 只有在 Angular2 尝试第一次渲染视图之后才会被设置。? 防止子表达式的其余部分被评估,直到 ? 左侧的部分变为 != null(Elvis 或安全导航运算符)。 - Günter Zöchbauer
3
在上面的代码中,您使用异步管道两次订阅相同的资源-最好使用 as 语法: `<ul *ngIf="(list$| async as list)?.length > 0; else loading"> <li *ngFor="let listItem of list"> {{ listItem.text }} </li></ul>将订阅存储在模板变量list` 中(注意没有美元符号),然后在模板中使用此变量-从而避免多个订阅。 - codeepic
显示剩余11条评论

41

一种解决.ts文件的方案:

     this.list.subscribe(result => {console.log(result.length)});

需要立即取消订阅吗? - Peter
最好在 onDestroy 组件中取消订阅可观察对象。 - ptheodosiou
@ThPadelis 这取决于可观察对象的生命周期... - crush

25

如果是 Angular 4+,请尝试以下方法

<div *ngIf="list$ | async;let list">
    Length: {{list.length}}
    <div *ngIf="list.length>0">
        <ul>
            <li *ngFor="let item of list">
                {{item.firstName}}
            </li>
        </ul>
    </div>
</div>

12

虽然这个答案是正确的

<div *ngIf="(list$ | async)?.length === 0">No records found.</div>

请记住,如果您正在使用http客户端调用后端(在大多数情况下是这样),如果您有超过一个 list$ | async ,您的API将会得到重复调用。这是因为每个| async管道都会创建一个新的订阅者到您的list$可观察对象。


4
也可以缩写为:
<div *ngIf="!(list$ | async)?.length">No records found.</div>

只需要在括号前使用感叹号即可。

3
这是对我有用的方法 -
*ngIf="!photos || photos?.length===0"

我正在使用httpClient异步获取数据。

这里的所有其他选项都没有起作用,让人失望。特别是那个性感的(list$ | async)管道。

Basa..


1

我在构造函数中初始化了 Observable<Customer[]>,但是当尝试隐藏容器 div 时,它会显示 "object is possibly undefined" 的错误信息,因为数组长度为空。

于是我这样写:<div *ngIf="(similarCustomers$ | async)?.length > 0">

我的同事解决了这个问题:

<div *ngIf="(similarCustomers$ | async) as similarCustomers">
  <ng-container *ngIf="similarCustomers.length > 0">

-3

ionic 4

<div *ngIf="(items | async)?.length==0">No records found.</div>

当我移除了$符号时,它就起作用了。


$符号用于表示Observable。它与工作/逻辑无关,只是Angular中遵循的一种约定。 - Anand Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接