Angular没有在rxjs管道中使用布尔变量更新视图



我对Angular 14有一个问题,它在查询数据时没有更新视图。

当从服务器加载数据时,我想在HTML中显示一个加载微调器。我使用ngbTypeahead提供建议/提示。当我在函数中设置布尔值时,它不会在视图中显示任何内容。我尝试使用NgZonerun方法更新角度力视图,但似乎对我不起作用

这是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);
});
}
}

希望它能帮助你或给你一些新的想法

最新更新