我对Angular 14有一个问题,它在查询数据时没有更新视图。
当从服务器加载数据时,我想在HTML中显示一个加载微调器。我使用ngbTypeahead
提供建议/提示。当我在函数中设置布尔值时,它不会在视图中显示任何内容。我尝试使用NgZone
和run
方法更新角度力视图,但似乎对我不起作用
这是TS
public isLoadingVisible: boolean = false
public suggestStations: OperatorFunction<string, Array<Station>> = (text$: Observable<string>) => {
this.zone.run(() => this.isLoadingVisible = true)
const suggestion = text$.pipe(
debounceTime(200),
distinctUntilChanged(),
switchMap((searchText: string) => this.dataService.suggestStations(searchText.toLowerCase())),
);
this.zone.run(() => this.isLoadingVisible = false)
return suggestion
}
// Also tried to put loading into the switchMap function, nut not working as well
public suggestStations: OperatorFunction<string, Array<Station>> = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
switchMap((searchText: string) => {
this.zone.run(() => this.isLoadingVisible = true)
const result = this.dataService.suggestStations(searchText.toLowerCase())
this.zone.run(() => this.isLoadingVisible = false)
return result
}),
);
}
HTML视图
<p *ngIf="isLoadingVisible">Loading...</p>
<div class="input-group mb-4">
<input [(ngModel)]="selectedStation"
[editable]='false'
[inputFormatter]="formatter"
[ngbTypeahead]="suggestStations"
[resultFormatter]="formatter"
[resultTemplate]="station_row"
class="form-control p-2"
placeholder="Název stanice"
type="text">
</div>
你知道问题出在哪里吗?非常感谢你的帮助!
看起来ngbTypeahead
内部订阅了suggestStations
。在这两种情况下,您所拥有的都是不正确的,因为您没有等待内部Observable完成,或者您在链外更改了isLoadingVisible
。
因此,您应该做的是将isLoadingVisible
放入链中,并确保您自己触发更改检测。
constructor(
private cdr: ChangeDetectorRef,
) {}
...
public suggestStations: OperatorFunction<string, Array<Station>> = (text$: Observable<string>) => {
return text$.pipe(
tap(() => {
this.isLoadingVisible = true;
this.cdr.markForCheck();
}),
debounceTime(200),
distinctUntilChanged(),
switchMap((searchText: string) => this.dataService.suggestStations(searchText.toLowerCase())),
tap(() => {
this.isLoadingVisible = false;
this.cdr.markForCheck();
}),
);
}
我使用了类似的东西
pipe(tap(() => this.loading.showLoading()),
finalize(() => this.loading.hideLoading())
其中加载和注入类以全局处理此变量。我在区域外执行,以避免自动触发刷新,并使用时间为零的setTimeout运行一次视图刷新(可能不是超级干净的代码,但正在工作(
@Injectable({ providedIn: 'root' })
export class Loading{
showLoading(): void {
this.zone.runOutsideAngular(() => {
setTimeout(() => {
this._isLoading$.next(true);
}, 0);
});
}
}
希望它能帮助你或给你一些新的想法