Angular ngrx/store-为什么可观察到的订阅方法返回以前的状态



问题似乎超出了我的能力。我已经正确地构建了存储,现在我无法从存储中检索当前元素。

showDialog(id_clicked) {
this.id = id_clicked
this.store.dispatch(new action.loadExampleAction(this.id));
this.observable$ = this.store.select(selectors.getObject);
}

通过这个简单的例子;可观察的";每当单击按钮时,调度具有当前选定id的新操作。在控制台中显示this.observable$将正确显示其有效负载中当前选定的对象。但现在当我这样做时:

tmp: <Object> = null
showDialog(id_clicked) {
this.id = id_clicked
this.store.dispatch(new action.loadExampleAction(this.id));
this.observable$ = this.store.select(selectors.getObject);
this.observable$.subscribe(object => {
this.tmp = object
}, first())
console.log(this.tmp)
}

subscribe内部的tmp返回上一个状态。即,如果我一开始点击id=1的对象,它将返回"0";"未定义";,然后当我点击id=2的对象时,它会返回id=1的对象,依此类推。即使this.observable$上的console.log显示其有效负载(值(是正确的。我不确定发生了什么。我不能简单地从这个可观察到的值中检索当前值。如果需要更多信息,我会提交更多信息。

您应该尽可能避免破坏Observable链,也避免使用局部变量。不要使用tmp变量,而是保留observable$,并在ngOnInit()中实例化它。然后,无论您在哪里需要使用observable$,都可以适当地订阅它(通常使用async管道(:

ngOnInit() {
this.observable$ = this.store.select(selectors.getObject);
}
showDialog(idClicked: string) {
this.store.dispatch(new action.loadExampleAction(this.id));
}

稍后,在某个模板中:

<ng-container *ngIf="observable$ | async as myStuff">
</ng-container>

不确定,但似乎您试图只获取first()订阅中出现的第一个值。

NgRx对选择器使用记忆,并且如果该选择器的状态尚未更改,则可以返回以前的值。因此,当您订阅它时,它的返回init值未定义,单击后,您将状态设置为";1〃;,但你没有得到它,因为你只获得了订阅中的第一个值。

点击也是异步操作,所以当你第二次点击新订阅创建的下一个对象并立即返回存储在商店中的值时,它是1,你会在屏幕上看到它,并且只有在那之后,因为";点击";异步性质存储中的新值变为"异步";2〃;,但直到单击下一个对象并看到旧值,您才看到它。

作为解决方案,您可以在代码中删除first()选项,但您将获得两个值,上一个和下一个,即当前值。为了避免它,你可以尝试使用";重置记忆化选择器";通过release((;函数,然后过滤管道中的"null"值,如下所示:

store
.pipe(
select(selectValues),
filter(val => val !== null)
)
.subscribe(/* .. */);

最新更新