如何根据 angular 中的承诺执行 ngIf?

How to do a ngIf based on a promise in angular?

我正在尝试执行 ngIf,结果取决于承诺。

模板

<div>
  <select [(ngModel)]="carValue" name="carName">
    <option value="renault">Renault</option>
    <option value="bmw">Bmw</option>
  </select>
  <p *ngIf="isDisplayed()">Good choice!</p>
</div>

至此,显示的功能为

isDisplayed() {
  return this.carValue === 'bmw';
}

但我希望它是异步的。像

isDisplayed() {
  return this.getBestChoice().then((result) => result);
}

getBestChoice() {
  // fake http call
  return new Promise((resolve) => {
    setTimeout(() => resolve('bmw'), 3000);  
  });
}

显然不行。我知道如何实现它,但不确定它是否干净。

这里是punker.

为什么不使用 Observables,这是 Angular 的方式。您可以通过 AsyncPipe 将其中一个设置为 public 属性 和 运行,后者将为您处理 sub/unsub 和更改检测触发。

import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { timer } from 'rxjs/observable/timer';
import { map, share, tap } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  carValue = '';
  showCongrats$: Observable<boolean>;
  check() {
    // fake API call
    this.showCongrats$ = timer(1000).pipe(
      map(() => 'bmw'), // "API" says bmw rocks
      tap(console.log),
      map(bestCar => this.carValue === bestCar),
      share() // so multiple async pipes won't cause multiple API calls
    );
  }
}

模板:

<div>
    <select [(ngModel)]="carValue" (change)="check()">
    <option value="">Choose</option>
    <option value="renault">Renault</option>
    <option value="bmw">Bmw</option>
  </select>
    <p *ngIf="showCongrats$|async">Good Choice!</p>
    <p *ngIf="carValue && (showCongrats$|async) === false">Not the Best Choice!</p>
</div>

工作堆栈闪电战: https://stackblitz.com/edit/angular-cxcq89?file=app%2Fapp.component.ts

我是这样解决的:

class.ts

export class FieldHeaderSectionComponent implements OnInit {
  hasBody: Promise<boolean>;

  constructor() {
    this.hasBody = this.haveBody();
  }
  
  public haveBody() : Promise<boolean> {
    // ... logic
    return Promise.resolve(false);
  }  
}

template.html

<div *ngIf="hasBody | async">...</div>