我有一个ponyracer应用程序,该应用程序实现了ngrx存储。非常基本的功能:开始比赛,添加小马,删除小马,得分表。问题出在我删除或添加小马时-基本上,此功能是指创建或销毁小马组件。因此,任何出于某种原因在某个地方添加的Pony商店,甚至在销毁组件后-应用程序仍然可以访问所有添加和删除的小马,并且例如当我只需要查看现有小马的分数时(例如,以前(甚至以前)删除)显示小马
我使用store.select.pipe(...)。subscribe(),并且不需要使用onDestroy和unsubscribe()
races.component.ts
export class RacesComponent implements OnInit {
racesState: Observable<fromPonyRacer.State>;
constructor(private store: Store<fromApp.AppState>) { }
ngOnInit() {
this.racesState = this.store.select("raceList");
this.racesState.subscribe()
}
}
races.component.html
<pr-race *ngFor="let race of (racesState | async).races; let i = index"
[race]="race" [index]="i">
</pr-race>
race.component.ts
export class RaceComponent implements OnInit {
@Input() race: RaceModel;
@Input() index: number;
racesState: Observable<fromPonyRacer.State>;
constructor(private store: Store<fromApp.AppState>) { }
ngOnInit() {
this.racesState = this.store.select("raceList");
this.racesState.pipe(
tap(races => {
if(races.raceStatus) this.movePony();
})
)
.subscribe()
}
}
race.component.html
<div class="race">
<img class="pony-img" [src]="race.src">
</div>
当小马到达终点时,将调度动作并将小马添加到名为currentRaces的商店属性中,因此商店将跟踪哪个小马首先完成,然后是第二次,依此类推。
const initialState: State = {
races: [
new RaceModel(some data),
new RaceModel(some another data),
new RaceModel(some more data)
],
raceStatus: false,
raceCount: 0,
isNewrace: false,
poniesAreAboutToFinish: null,
currentRaces: []
}
但是,此操作也会分派给已删除的小马,它们也将到达store.currentRaces并显示在得分表中。而且我无法弄清楚这些小马从哪里来。因为state.races总是真实且正确的(根据redux dev工具),而races.component需要state.races来渲染每个小马的视图,所以它总是正确且新鲜的
movePony() {
some code for moving a pony
if(ponyReachedFinish) {
this.store.dispatch(new PonyRacerActions.StopRace({name: this.race.name, place, points})
}
}
如果需要更多详细信息,可以在这里找到完整的代码:https://github.com/joistick1/pr2
更新:问题已解决。正如我最初假设的那样,该问题是由于订阅泄漏引起的。我应用了OnDestroy,并在此方法中应用了一行代码 this.subscription.unsubscribe();
答案 0 :(得分:0)
在reducer中,当您删除小马时,您是直接在改变状态而不是返回新的不可变状态。尝试应用以下更改:
case PonyRacerActions.DELETE_PONY:
return {
...state,
races: state.races.filter(race => race != action.payload),
currentRaces: []
}