2017-10-30 3 views
1

Ich weiß nicht, ob dies eine gute Praxis ist oder nicht. Aber unten ist das, was ich zu tun versucht:wie ngrx-store arbeiten mit canLoad guard

Ich habe 2 faul geladene Module: ManagementModule und ConfigurationModule, und die Route Config ist wie folgt:

const routes: Routes = [ 
    {path: '', redirectTo: 'management', pathMatch: 'full'}, { 
    path: 'configuration', 
    loadChildren: './configuration/configuration.module#ConfigurationModule', 
    canLoad: [UnconfiguredGuard] 
    }, 
    { 
    path: 'management', 
    loadChildren: './management/management.module#ManagementModule', 
    canLoad: [ConfiguredGuard] 
    } 
] 

Grundsätzlich ist die Idee war, den Systemstatus zu überprüfen und Umleitung auf verschiedene Phasen, z. Wenn sys noch nicht konfiguriert ist, leiten Sie an um, andernfalls wird an umgeleitet.

Bevor ich @ngrx/store in das Projekt aufgenommen, die zwei canLoad Wache sind einfach:

// ConfiguredGuard: 
canLoad(route) { 
    return this.configService.isConfigured() 
     .do((configured: boolean) => { 
      if (!configured) { 
      // redirect to /configuration if unconfigured 
      this.router.navigate(['/configuration']); 
      } 
     }) 
} 

Jetzt will ich alle @ nehmen NGRX/{Speicher, Effekte, Router-Speicher} Libs, und die oben Wache wird dann geändert:

canLoad(route) { 
    this.store.dispatch(new CheckInitStatus()); 
    return this.store.select('initStatus') 
     .filter(s => s.checked) // check only when loaded 
     .map(s => s.status === 'initialized') 
     .catch(() => of(false)); 
} 

natürlich ist die Nebenwirkung definiert:

@Effect() 
    check$: Observable<InitStatusAction> = this.actions$ 
    .ofType<CheckInitStatus>(CHECK_INITSTATUS) 
    .mergeMap(() => this.fetchInitStatus()) 
    .map(status => new InitStatusChecked({status, checked: true})) 
    .catch(e => of(new InitStatusCheckFailure(e))); 

Aber die Navigation wurde nicht ausgeführt, es wird keine ROUTER_NAVIGATION Aktion ausgegeben. Ist etwas, was ich hier verpasst habe? Und ich frage mich auch, ob dies eine gute Praxis ist? Ich fand einige Beispiele von canActivate Schutz Verwendung, aber keine für canLoad Schutz. Bitte helfen Sie, danke!

Antwort

1

Endlich habe ich es herausgefunden, nach einem ganzen Tag Debugging! Die Lösung ist aber ganz einfach, fügen Sie first() oder take(1) in die Operator-Kette nach filter() hinzu, ich kann das Gefühl, das ich jetzt habe, nicht ausdrücken ... aber ich erkenne, dass ich eine Einstellung für die korrekte Verwendung von RxJS brauche.

canLoad(route) { 
    this.store.dispatch(new CheckInitStatus()); 
    return this.store.select('initStatus') 
     .filter(s => s.checked) // check only when loaded 
     .first() // or equivalently take(1) 
     .map(s => s.status === 'initialized') 
     .catch(() => of(false)); 
} 

ich sorgfältig die Beispiele von canActivate mehr lesen sollte dies take(1)/first() Operator ist alles, was es zum Beispiel: https://toddmotto.com/preloading-ngrx-store-route-guards

+0

Hallo @RoyLing! Danke für diese Antwort, es hat mir sehr geholfen (ich hatte das gleiche Problem). Können Sie mir sagen, wo Sie die Routenführung aufgerufen haben? Rufen Sie innerhalb von ngrx Effekte, innerhalb von Komponenten ... w –

+0

@PedroArantes dies war ein Problem in einem früheren Projekt vor langer Zeit, ich hätte fast vergessen, was ich zu der Zeit tat ... jedenfalls, ich denke, ich tat das Navigation hier in dieser Wache selbst, nur nach dem Beispiel auf eckigen Doc. Ich hoffe es hilft. –