如何根据 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);
});
}
显然不行。我知道如何实现它,但不确定它是否干净。
- 绑定事件 ngModelChange。每次用户选择一辆新车。它重新加载一个变量 "isDisplayed"
- 保存承诺并在模板中使用 ync 管道。但它不会重新加载数据。
这里是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>
我正在尝试执行 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);
});
}
显然不行。我知道如何实现它,但不确定它是否干净。
- 绑定事件 ngModelChange。每次用户选择一辆新车。它重新加载一个变量 "isDisplayed"
- 保存承诺并在模板中使用 ync 管道。但它不会重新加载数据。
这里是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>