javascript - Observable 订阅触发后 Angular UI 未更新
问题描述
我有一个角度页面,它使用服务中的可观察参数。但是,当这个 observable 更新时,页面不会更新以匹配。
我尝试将 observable 的结果存储在一个平面值中,或者更改一个布尔值来调整 UI,但似乎没有任何效果。
记录 observable 确认它确实更新正确,并且在重新导航到页面时显示新值。
其他条件 UI 更新正确地修改了页面,只有以下 ( *ngIf="(entries$ | async), else loading"
) 中的一个导致了此问题。
组件.ts
export class EncyclopediaHomeComponent implements OnInit {
entries$: Observable<EncyclopediaEntry[]>;
categories$: Observable<string[]>;
entry$: Observable<EncyclopediaEntry>;
entry: EncyclopediaEntry;
isEditing: boolean;
constructor(private route: ActivatedRoute, private encyService: EncyclopediaService) {
this.entries$ = encyService.entries$;
this.categories$ = encyService.categories$;
this.entries$.subscribe(es => {
console.log(es);
});
route.url.subscribe(url => this.isEditing = url.some(x => x.path == 'edit'));
this.entry$ = route.params.pipe(
switchMap(pars => pars.id ? encyService.getEntry(pars.id) : of(null)),
);
this.entry$.subscribe(entry => this.entry = entry);
}
ngOnInit(): void {
}
updateEntry(entry: EncyclopediaEntry) {
this.encyService.updateEntry(entry.id, entry);
}
}
组件.html
<div class="encyclopedia-container">
<ng-container *ngIf="(entries$ | async), else loading">
<app-enc-list [entries]="entries$ | async"
[selectedId]="entry ? entry.id : null"></app-enc-list>
<ng-container *ngIf="entry">
<app-enc-info *ngIf="!isEditing, else editTemplate"
[entry]="entry$ | async"></app-enc-info>
<ng-template #editTemplate>
<app-enc-edit [entry]="entry$ | async" [categories]="categories$ | async"
(save)="updateEntry($event)"></app-enc-edit>
</ng-template>
</ng-container>
</ng-container>
<ng-template #loading>
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
<br>
<p>Loading Encyclopedia...</p>
</ng-template>
</div>
编辑: service.ts
export class EncyclopediaService {
entriesSubject = new ReplaySubject<EncyclopediaEntry[]>();
entries$ = this.entriesSubject.asObservable();
private _entries: EncyclopediaEntry[];
constructor(private file: FileService) {
file.readFromFile(this.projectName+'Encyclopedia').subscribe((es: string) => {
this._entries = JSON.parse(es);
this.entriesSubject.next(this._entries);
this.entries$.subscribe(es => this.file.writeToFile(this.projectName+'Encyclopedia', JSON.stringify(es)));
});
}
.
.
.
}
解决方案
该组件似乎没有看到变化。我不知道为什么,因为 |async 会完成这项工作。
但要修复它,您可以使用 ChangeDetector:
constructor(
private route: ActivatedRoute,
private encyService: EncyclopediaService
private changeDetectorRef: ChangeDetectorRef,
) {
this.entries$ = encyService.entries$;
this.categories$ = encyService.categories$;
this.entries$.subscribe(es => {
// setTimeout need to run without troubles with ng changes detector
setTimeout(_=>{this.changeDetectorRef.detectChanges()},0);
...
});
或者您可以像那里描述的那样使用 markforCheck 。
推荐阅读
- reactjs - 如何支持从更新的网站切换到旧网站?
- xml - XSL for-each 只显示第一条记录
- xslt - XSLT 显示唯一的对象名称
- backup - Does OneDrive backup produce any type of error logging?
- javascript - 存储初始状态为数组时如何实现Reducer?
- javascript - Migrating Js plugins to Vue
- r - extracting standard errors for long-run coefficients from an ARDL model
- r - How to set a lower SSL security in Debian 9?
- php - Hide products from Woocommerce REST API
- javascript - How to use Datatables column data (done in js) in action button url's last segment?