【问题标题】:angular 2 *ngFor, when iterable hasn't be instantiated yetangular 2 *ngFor,当iterable还没有被实例化时
【发布时间】:2016-08-25 04:19:19
【问题描述】:

我有几个 *ngFor 循环取决于可能尚未实例化的可迭代对象。 (例如,他们正在等待一个 observable)

我可以在视图中使用这样的表达式吗?

更新: 这是抛出错误的部分

组件

activeLectureContent:LectureContent;

查看

  <div class="filter-units">
    <div>Units</div>
    <a (click)="setUnit(i)" class="btn btn-icon-only blue filter-unit-btn" *ngFor="#unit of activeLectureContent.content; #i = index">
      <span>{{i+1}}</span>
    </a>
  </div>

无法读取 [null] 中未定义的属性“内容”

讲座内容是这样的

export class LectureContent{
  constructor(
    public name:string = '',
    public filter:LectureFilter[]=[],
    public show:boolean = true,
    public hover:boolean = false,
    public content:any[]=[]
  ){}
}

干杯

【问题讨论】:

  • 这会导致错误吗?通常,如果 iterable 尚不存在,您无需执行任何操作。
  • 是的,iterable 包含大对象和 div 中需要访问的元素

标签: angular ngfor


【解决方案1】:

您可以使用ngIf 指令,因此只有当iterable 是thruthy 时才会呈现它。

<div *ngIf="iterable" *ngFor="let item of iterable"><div>

【讨论】:

  • 嗨!感谢您的回复,我已经更新了我的问题,因为我认为我不是直接在可迭代对象上循环,而是它是一个尚未实例化的对象内的数组。
【解决方案2】:

您正在寻找 AsyncPipe:

<div *ngFor="#item of iterable | async"></div>

它适用于 Observables、Promises 和 EventEmitters。您可以在guide(章节“不纯的 AsyncPipe”)和documentation 中获得更多信息。

【讨论】:

  • 嗨!感谢您的回复,我已经更新了我的问题,因为我认为我不是直接在可迭代对象上循环,而是它是一个尚未实例化的对象内的数组。
【解决方案3】:

如果它“简单地”是一个可迭代的(数组,...但不是可观察的,promise),我认为没有什么可做的。 ngFor 将检查迭代的更新。当值变为不为空时,ngFor会更新相应的内容:

查看此示例:

@Component({
  selector: 'app'
  template: `
    <div>
      <div *ngFor="#category of categories;#i=index">{{i}} - {{category.name}}</div>
    </div>
  `
})
export class App {
  constructor() {
    Observable.create((observer) => {
      setTimeout(() => {
        observer.next();
      }, 2000);
    }).subscribe(() => {
      this.categories = [
        { name: 'Cat1', value: 'cat1' },
        { name: 'Cat2', value: 'cat2' },
        { name: 'Cat3', value: 'cat3' },
        { name: 'Cat4', value: 'cat4' }
      ];
    });
  }
}

看到这个 plunkr:https://plnkr.co/edit/J1aVclVcjJPqm1Qx9j0j?p=preview

使用 beta 17,您需要将 # 替换为 let

<div *ngFor="let category of categories;let i=index">{{i}} - (...)

ngIfngFor 似乎效果不佳。看到这个plunkr:https://plnkr.co/edit/aE3umzzSZ5U9BocEE9l6?p=preview

如果“iterable”是可观察的或承诺的,则将异步管道排入队列。

编辑

你可以试试这样的:

<template [ngIf]=" activeLectureContent ">
    <a (click)="setUnit(i)" class="btn btn-icon-only blue filter-unit-btn" *ngFor="#unit of activeLectureContent.content; #i = index">
      <span>{{i+1}}</span>
    </a>
</template>

我使用 ngIf 的扩展语法,因为 ngFor 和 ngIf 不能用于同一个元素。

【讨论】:

  • 嗨蒂埃里,我已经更新了我的问题。也许我的迭代不是一个简单的迭代?因为它是一个尚未实例化的对象内部的数组?如果我让你正确,如果 ngFor 直接连接到可迭代对象,它不会抛出错误?
  • 嘿!您需要检查 activeLectureContent 是否未定义。我更新了我的答案。也许可以使用 Elvis 运算符:“activeLectureContent?.content”。但我不知道它是否适用于这种情况(ngFor)。
  • 谢谢!猫王真的很安全;)
  • 猫王真的适用于 activeLectureContent?.content。但是它不适用于 activeLectureContent?.content[activeUnit]?.tasks 因为我猜内容是一个数组而不是一个对象?至于 ngIf = false,表示整个块根本不会被渲染,所以里面的任何未实例化的变量都不会导致错误。
  • 太棒了!也许你可以试试这个:“activeLectureContent?.content?[activeMent].tasks”
【解决方案4】:

因为我最近有同样的问题,所以重新发布这篇文章。

这是 Angular (safe navigation operator) 的完美案例。

来自文档:

Angular 安全导航运算符 (?.) 是防止属性路径中出现空值和未定义值的一种流畅而方便的方法。

所以问题中的示例视图是:

  <div class="filter-units">
    <div>Units</div>
    <a (click)="setUnit(i)" class="btn btn-icon-only blue filter-unit-btn" 
      *ngFor="let unit of activeLectureContent?.content; let i = index">
      <span>{{i+1}}</span>
    </a>
  </div>

添加 ?在 activeLectureContent 之后意味着如果 activeLectureContent 为 null 或未定义,ngFor 将被忽略。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2013-09-06
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 2016-08-03
    • 2019-09-23
    • 2016-08-28
    相关资源
    最近更新 更多