2017-04-23 6 views
0

Ich entwickle gerade eine Anwendung mit Angular mit Redux-Prinzip mit ngrx.Rufen Sie Komponentenlogik, wenn sich der Zustand in ngrx ändert

Ich bin auf der Suche nach einer Best Practice für die Reaktion auf Zustandsänderungen und rufen Sie einige Komponentenlogik abhängig von diesem Zustand. Ich gebe Ihnen ein (vereinfachtes) Beispiel deutlich zu machen, was ich meine:

reducers.ts

import {createSelector} from 'reselect'; 

export const getViewTypeOrFilterChanged = createSelector(isLoading, getActiveViewType, getActiveFilter, (isLoading, activeViewType, activeFilter) => { 
    // ensure that data is loaded 
    if (!isLoading) { 
     return { 
      activeViewType: activeViewType, 
      activeFilter: activeFilter 
     }; 
    } 
}); 

Beispiel-component.ts

@Component({ ... }) 
export class ExampleComponent implements OnInit { 

    // properties ... 

    constructor(private store: Store<fromRoot.AppState>) { 
    } 

    ngOnInit() { 
     this.subscriptions.push(
      this.store.select(fromRoot.getViewTypeOrFilterChanged).subscribe((result) => { 
       if (result) { 
        this.property1 = result.activeType; 
        this.dependentHelperClass.method1(result.activeFilter); 

        this.method1(); 
        this.method2(result.activeFilter); 
        this.method3(); 
       } 
      }) 
     ); 
    } 

    ngOnDestroy() { 
     this.subscriptions.forEach((subscription: Subscription) => { 
      subscription.unsubscribe(); 
     }); 
    } 

    // methods ... 
} 

Wie Sie können siehe Ich verwende auch reselct, um drei verschiedene Status-Slices in einem Selektor zu kombinieren (getViewTypeOrFilterChanged). In der Subskription zu diesem Selektor möchte ich dann einige Aktionen entsprechend dem kombinierten Zustand durchführen.

Die Sache ist, ich fühle mich wie ngrx Store und Abonnements mehr in einer Art von Publish/Subscribe-Muster hier und es fühlt sich nicht ganz richtig an. Auch die Subskriptionen (ich habe mehrere) in ngOnInit und Abmeldungen in ngOnDestroy stören mich, aber ich kann mir keinen Weg vorstellen, wie ich z. asynchrone Leitung Gibt es vielleicht eine elegantere Art, auf (kombinierte) Zustandsänderungen zu reagieren?

Danke!

Antwort

0

Mit RxJS sollte man sich alles als Stream vorstellen - der folgende Code ist nur ein Beispiel, weil ich nicht wirklich etwas von deiner UI-Logik kenne, also sieh dir nur die Struktur an und nicht die Logik des Code, da es eher wie eine sehr wilde Vermutung von mir ist:

@Component({ ... }) 
export class ExampleComponent implements OnInit { 
    private destroyed$ = new Subject<boolean>(); 

    // the following streams can be used in the controller 
    // as well as in the template via | async 
    // the .share() is just so the | async pipe won't cause unneccessary stream-creations (the result should be the same regardless of the .share(), it's just a minor performance-enhancement when using multiple | async) 
    isLoading$ = this.store.select(fromRoot.isLoading).share(); 
    activeViewType$ = this.store.select(fromRoot.getActiveViewType).share(); 
    activeFilter$ = this.store.select(fromRoot.getActiveFilter).share(); 
    activeViewTypeAndFilter$ = Observable.combineLatest(this.activeViewType$, this.activeFilter$).share(); 

    constructor(private store: Store<fromRoot.AppState>) { 
    } 

    ngOnInit() { 
     this.isLoading$ 
      .filter(isLoading => !isLoading) // the initial stream will not emit anything until "loading" was false once 
      .switchMapTo(this.activeViewTypeAndFilter$) 
      .do([viewType, filter] => { 
       this.dependentHelperClass.method1(activeFilter); 

       this.method1(); 
       this.method2(activeFilter); 
       this.method3(); 
      }) 
      .takeUntil(this.destroyed$) //this stream will automatically be unsubscribed when the destroyed$-subject "triggers" 
      .subscribe(); 
    } 

    ngOnDestroy() { 
     this.destroyed$.next(true); 
     this.destroyed$.complete(); 
    } 

    // methods ... 
} 

wie gesagt: Logik-weise kann ich nicht sagen, ob dies ist, was Sie brauchen, aber das ist nur eine Frage von verschiedenen Betreibern und/oder einen unterschiedliche Reihenfolge, um Ihren "Main-Stream" anders zu gestalten.

Verwandte Themen