CombineLatest 被触发,尽管源没有改变

CombineLatest is triggered although sources did not change

我正在使用 Angular 作为前端

grid$: Observable < any[][] > | null = null
ngOnInit() {
    this.grid$ = combineLatest([this.route.queryParams, source1, source2])
        .pipe(
            map(data => {
                 window.scroll(0,0) // go to top when route params change
                //do something with the sources and route params
                return grid;
            })
        )
}

我正在使用 grid$ 和异步管道

<ng-container *ngIf="grid$ | async as grid>
<div *ngFor="let column of columns>
    <div *ngFor="let analyse of grid[column]"> ... </div>
</div>
</ng-container>

工作正常。

现在我想在特定事件发生后更改网格


changeGrid() {
    // I also tried to just use map without assignment and return a new grid but then nothing happens
    this.grid$ = this.grid$.pipe(
        map(grid => {
            // do something with grid
            return grid;
        })
    }
}

这也有效。我唯一的副作用是 combineLatest 也会被触发,尽管源没有改变,所以你会自动滚动到顶部,这不是预期的。有人可以向我解释为什么吗?我在 combineLatest 中使用 distinctUntilChanged 尝试过,但在使用 changeGrid() 时不再触发。我按以下方式使用 distinctUntilChanged

distinctUntilChanged((prev,curr) => 
{ 
    return prev[0].get("id") != curr[0].get("id")
}) 

首先,通过写入 this.grid$ = ...,您失去了对其先前值的内存引用。这意味着您无法停止 combineLatest 中的前一个可观察对象。这可能是您遇到问题的原因。

其次,由于您使用了 queryParams observable,这意味着在每次查询参数更改时,您的 observable 都会被触发。您没有提供足够的代码来证明是否属于这种情况,但这也可能是您问题的另一个原因。

最后,distinctUntilChanged 比较内存引用:当与 combineLatest 一起使用时,除非您为其提供函数,否则运算符是无用的(每次 combineLatest 发出时都会创建一个新数组).