我正在尝试根据条件显示路由链接名称。如果条件为true,我想显示div部分routerLink的名称。如果我选中{{isNameAvailable}}
,它首先显示false
,在this.names
得到值后,它显示true
。由于在组件中getDetails()
方法是异步的,this.names
在html模板渲染后得到值。因此,此routerLink不会显示。因此,我想在一段时间后显示div部分。(这就是我的解决方案(不知道是否还有其他解决方案。
这是我的html文件代码。
<main class="l-page-layout ps-l-page-layput custom-scroll bg-white">
{{isNameAvailable}}
<div class="ps-page-title-head" >
<a *ngIf ="isNameAvailable === true" [routerLink]="['/overview']">{{Name}}
</a>
{{Name}}
</div>
</main>
这是我的组件.ts文件
names= [];
isNameAvailable = false;
ngOnInit() {
this.getDetails()
}
getDetails() {
this.route.params.subscribe(params => {
this.names.push(params.Names);
console.log(this.names);
this.getValues().then(() => {
this.isNameAvailable = this.checkNamesAvailability(this.names);
console.log(this.isNameAvailable);
});
});
}
resolveAfterSeconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 900);
});
}
checkNamesAvailability(names) {
console.log(names);
return names.includes('Sandy');
}
async getValues() {
await this.resolveAfterSeconds(900);
}
console.log(this.isLevelAvailable);
也成立。我能为此做些什么?
1。您在HTML中没有任何内容可显示,只有isNameAvailable
,因为您在Name
变量中没有任何赋值。
2.异步管道最好使用角度内置,当您想要显示observables的返回值时。
3.当你使用*ngIf
指令时,你可以跳过*ngIf ="isNameAvailable === true"
检查,因为变量是布尔型,你可以写*ngIf ="isNameAvailable"
,它也会检查null
,但不会检查未定义的
- 它之所以有效,是因为
*ngIf
指令负责检查和呈现UI,您可以通过调用函数来查看该指令检查了多少次,并在控制台中打印和回答
组件注释中是否设置了changeDetection: ChangeDetectionStrategy.OnPush
文档?这也许可以解释这种行为。有了它,Angular只对组件@Input()
的更改进行更改检测,因为在您的情况下没有,所以它没有运行更改检测,这就是为什么模板没有更新的原因。你可以评论这一行,以检查这是否是问题的原因。您始终可以通过ChangeDetectorRef.detectChange()
文档手动运行更改检测,这将解决问题
constructor(private cd: ChangeDetectorRef) {}
...
getDetails() {
this.route.params.subscribe(params => {
...
this.getValues().then(() => {
this.isNameAvailable = this.checkNamesAvailability(this.names);
this.cd.detectChanges(); // solution
console.log(this.isNameAvailable);
});
});
}
这个stackblitz展示了这个bug和解决方案。你可以在这里阅读更多关于变化检测的
您可以将RxJStimer
函数与switchMap
运算符一起使用,而不是使用Promise来在特定时间后触发某些内容。
尝试以下
import { Subject, timer } from 'rxjs';
import { takeUntil, switchMap } from 'rxjs/operators';
names= [];
isNameAvailable = false;
closed$ = new Subject();
ngOnInit() {
this.getDetails()
}
getDetails() {
this.route.params.pipe(
switchMap((params: any) => {
this.names.push(params.Names);
return timer(900); // <-- emit once after 900ms and complete
}),
takeUntil(this.closed$) // <-- close subscription when `closed$` emits
).subscribe({
next: _ => {
this.isNameAvailable = this.checkNamesAvailability(this.names);
console.log(this.isNameAvailable);
}
});
}
checkNamesAvailability(names) {
console.log(names);
return names.includes('Sandy');
}
ngOnDestroy() {
this.closed$.next(); // <-- close open subscriptions when component is closed
}