【问题标题】:Angular/Typescript - Solve Async in ArrayAngular/Typescript - 解决数组中的异步问题
【发布时间】:2018-09-11 19:10:56
【问题描述】:

我们有 2 个数组 SpeisekarteEssensplan - 我想调用方法 printName,打印出名称,我从身份证。

问题是,“名称”总是未定义。

“错误类型错误:无法读取未定义的属性‘名称’”

如何在模板中修复异步方法?

模板(printName(essenName) 中的异步)

<div *ngFor="let i of essensplan"> <br />
  <div><b>Woche : {{i.id}}</b></div> <br />
  <button *ngFor="let id of i.essenProWoche" (click)="print(id)">Gericht 
** {{printName(id)}} ** </button> 

组件

ngOnInit() {
  console.log("ngOnInite essensplan.component")
  this.getSpeisekarte();
  this.getEssensplan();

}

printName(id: number) {
  this.essenName = this.speisekarte.find(i => i.id == id ).name

 getSpeisekarte(): void {
  this.essenService.getSpeisekarte()
  .subscribe(speisekarte => this.speisekarte = speisekarte);
}

getEssensplan(): void {
  this.essensplanService.getEssensplan()
    .subscribe(essensplan => this.essensplan = essensplan)

}

【问题讨论】:

  • 在您的模板中 essenName 未定义。你是说{{printName(id)}} 吗?
  • 哦,是的,对不起。将编辑它。

标签: angular typescript asynchronous


【解决方案1】:

我不确定是否可以延迟整个组件,直到两个 HTTP 调用都完成。取而代之的是,您可以修改printName 以处理尚未加载this.speisekarte 的情况。然后,告诉组件一旦加载就重新加载。

组件

constructor(private changeDetector: ChangeDetectorRef) {}

ngOnInit() {
  console.log("ngOnInite essensplan.component")
  this.getSpeisekarte();
  this.getEssensplan();
}

printName(id: number) {
  const match = this.speisekarte.find(i => i.id == id );
  return match ? match.name : "";
}

getSpeisekarte(): void {
  this.essenService.getSpeisekarte()
  .subscribe(speisekarte => {
    this.speisekarte = speisekarte;
    this.changeDetector.markForCheck();
  });
}

getEssensplan(): void {
  this.essensplanService.getEssensplan()
  .subscribe(essensplan => { 
    this.essensplan = essensplan;
    this.changeDetector.markForCheck();
  });
}

现在,无论 HTTP 请求完成的顺序如何,模板都不会出错(尽管如果 getEssensplangetSpeisekarte 之前完成,则名称将为空


注意:我更改了printName 以返回一个值,因为这是显示它所必需的

【讨论】:

  • 你是个传奇。谢谢!
【解决方案2】:

你可以使用AsyncPipe "异步管道订阅一个 Observable 或 Promise 并返回它发出的最新值。当发出一个新值时,异步管道标记要检查更改的组件。当组件被破坏时,异步管道会自动取消订阅以避免潜在的内存泄漏。”

<div *ngFor="let i of essensplan | async "> <br />

或使用 NgIF 运算符安全地显示视图。

请检查Answer是否有同样的问题。

【讨论】:

    【解决方案3】:

    使用 Observables 解决您的问题。它们将显着减少和改进您的代码。 Angular 有一个名为 async-pipe 的内置管道,只要组件处于活动状态,它就会订阅。

    export class MyEssenComponent {
      essensPlan$: Observable<Essensplan>;
      speisekarte$: Observable<Speisekarte>;
    
      ngOnInit(): void {
        this.essensPlan$ = this.essensplanService.getEssensplan();
        this.speisekarte$ = this.essenService.getSpeisekarte();
      }
    
      get name(id: string): Observable<string> {
        return this.speisekarte$.pipe(
          filter(speisekarte => speisekarte.id === id),
          map(speisekarten => speisekarten[0] ? speisekarten[0].name : '')
        );
      }
    }
    

    然后您可以轻松地将您的模板重写为

    <div *ngFor="let i of essensplan$ | async"> <br />
      <div><b>Woche : {{i.id}}</b></div> <br />
      <button *ngFor="let id of i.essenProWoche" (click)="print(id)">
        Gericht ** {{name(id) | async}} **
      </button>
    </div>
    

    我还建议选择更有意义的变量名,因为它们完全令人讨厌。例如。您为 ID 数组选择了 essenProWoche 属性,或者只是将 i 作为变量。

    【讨论】:

      猜你喜欢
      • 2022-10-14
      • 2021-03-27
      • 2019-03-27
      • 2019-02-13
      • 2018-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多