簡體   English   中英

如何修復訂閱泄漏Angular Ngrx存儲

[英]How to fix subscription leak Angular ngrx store

我有一個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();。

在還原器中,當您刪除小馬時,您是直接更改狀態,而不是返回新的不可變狀態。 嘗試應用以下更改:

case PonyRacerActions.DELETE_PONY:
            return {
                ...state,
                races: state.races.filter(race => race != action.payload),
                currentRaces: []
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM