我有一个组件,可以渲染绑定到名为
Observable<Image[]>
的 sorted$
的图像网格。
<ng-container *ngFor="let image of sorted$ | async; index as i">
<img src="..."/>
</ng-container>
我还有一个下拉菜单,可用于对图像进行排序。我正在使用
fromEvent()
从名为 Observable<InputEvent>
的下拉列表选择事件中创建一个 sort$
。
this.sort$ = fromEvent<InputEvent>(this.sort.nativeElement, "input");
最后,我有另一个名为
Observable<Image[]>
的 source$
,它提供了所有要排序的图像:
source$!: Observable<Image[]>;
这个想法是根据用户选择的排序选项对图像进行排序。
this.sorted$ = combineLatest({ source: this.source$, sort: this.sort$ })
.pipe(map(images => { *** sort logic here ***}));
而且,它有效!除了一件事... 当页面首次显示时,不会渲染任何图像,因为
sorted$
未发出任何值 - 因为用户尚未选择排序选项。当用户选择一个选项时,一切都会正常 - 只是在初始渲染上不起作用。
sort$
和 sorted$
是在 ngAfterViewInit()
中创建的,因为 <select>
元素在此之前尚未绑定。然而,页面已经渲染完毕。
如果我最初将
sorted$
可观察量分配给 source$
函数中的 ngOnInit()
可观察量的值,页面将渲染图像,但是当稍后在 ngAfterViewInit()
中为其分配新值时,我得到错误:
Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
我有鸡和鸡蛋。在访问
<select>
元素之前如何渲染排序后的图像?
您可以使用 startWith rxjs 运算符
this.sort$ = fromEvent<InputEvent>(this.sort.nativeElement, "input")
.pipe(startWith(null));
或者你可以使用 merge 而不是combineLastest(当任何可观察到的变化时“调度”)
this.sorted$ = merge(this.source$, this.sort$ }).pipe((res:Image[] | string)=>{
..res can be the response to this.source$ or to this.sort$..
})