2017-10-04 3 views
0

MyComponent verwendet einen Dienst, um Daten abzurufen, und rendert diese Daten dann. Der Dienst kann jedoch keine Daten abrufen, bis der Benutzer angemeldet ist. Wenn der Benutzer zum ersten Mal auf die Route '/ myPage' zugreift, zeigt die Containerkomponente die Anmeldekomponente an. Obwohl die Anmeldekomponente anstelle von ng-content gerendert wird (was zu MyComponent führt), wird MyComponent von angular initialisiert und ruft den Service auf, Daten zu früh abzurufen, bevor er sich anmeldet. Deshalb, wenn sich der Benutzer erfolgreich anmeldet und MyComponent schließlich rendert, gibt es keine Daten, der ursprüngliche Datendienst ergab nichts.Wie wird die Funktion ausgeführt, wenn die Winkelkomponente gerendert wird?

Wie kann ich den Datenabruf verschieben, bis die Komponente gerendert ist? Ich habe alle verschiedenen Lebenszyklusmethoden in MyComponent ohne Erfolg ausprobiert.

app.component

<container> 
    <router-outlet></router-outlet> 
</container> 

Behälterkomponente

<div *ngIf="!userService.getLoggedInUser()"> 
    <login></login> 
</div> 

<div *ngIf="userService.getLoggedInUser()"> 
    <ng-content></ng-content> 
</div> 

Rangierbaugruppe

const routes: Routes = [ 
    { path: 'myPage', component: myComponent } 
]; 

meine Komponente

export class MyComponent { 
    data 

    constructor(private dataService: DataService) {} 

    ngOnInit() { 
     //how can i make run this service AFTER the component renders? i know 
     //ngOnInit is definitely not the correct lifecycle method, but what is? 
     this.dataService.get().then((data) => this.data = data); 

    } 
    } 
+0

Sie suchen: https://angular.io/api/core/AfterViewInit. Genauso wie OnInit (importieren, implementieren, dann verwenden Sie ngAfterViewInit() {...}) –

+0

Ich denke, Sie gehen auf dem falschen Weg. Denn in Ihrem Fall müssen Sie überall Ihre Bedingung zur Überprüfung hinzufügen, ob der Benutzer angemeldet ist oder nicht. Und das bedeutet, dass die Komponente geladen ist und wir alle js-Dateien finden und überprüfen können. Und vielleicht kann jemand einen XSS-Angriff machen. In eckigen haben wir den besseren Weg, Wache zu bauen. Dort können Sie ein gutes Beispiel finden: http://jasonwatmore.com/post/2016/09/29/angular-2-user-registration-and-login-example-tutorial –

+0

@RomaSkydan danke für die Info. Aber ich bin mir nicht sicher, was das Sicherheitsproblem ist? Ja, der Client sucht nach dem angemeldeten Benutzer, aber ich habe auch eine Sicherheitsüberprüfung serverseitig mit Tokens (deshalb muss ich Daten abrufen, nachdem sich ein Benutzer angemeldet hat). Können Sie genauer erläutern, wo das Sicherheitsproblem liegt? – Simon

Antwort

2

ngOnInit ist die normale Methode zum Abrufen von Daten für eine Komponente verwendet wird. Also, wenn etwas nicht funktioniert, denke ich, dass es irgendwo anders ein Problem gibt.

Strecke Wache

Zum Beispiel ein gemeinsamer Weg, um einen Login-Dialog zu präsentieren ist eine Route Wache zu verwenden, anstatt ngIf. Das wäre in etwa so aussehen:

import { Injectable } from '@angular/core'; 
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, 
     CanActivate } from '@angular/router'; 

import { AuthService } from './auth.service'; 

@Injectable() 
export  class AuthGuard implements CanActivate { 

    constructor(private authService: AuthService, 
       private router: Router) { } 

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 
     return this.checkLoggedIn(state.url); 
    } 

    checkLoggedIn(url: string): boolean { 
     if (this.authService.isLoggedIn()) { 
      return true; 
     } 

     // Retain the attempted URL for redirection 
     this.authService.redirectUrl = url; 
     this.router.navigate(['/login']); 
     return false; 
    } 
} 

Sie verwenden dann diese Wache auf jeder Strecke, die ein Protokoll in erfordert:

   { path: 'welcome', component: WelcomeComponent }, 
       { 
        path: 'movies', 
        canActivate: [AuthGuard], 
        loadChildren: './movies/movie.module#MovieModule' 
       }, 
       { path: '', redirectTo: 'welcome', pathMatch: 'full' }, 

Dies sollte zu früh, um das Bauteil verhindern Routing.

Strecke Resolver

Eine weitere Option, die Sie betrachten können, ist eine Route Resolver zu verwenden. Es ermöglicht Ihnen, die Daten für eine Route vor dem Routing zu der bestimmten Komponente abzurufen.

Ich bin mir nicht sicher, dass das in Ihrem Szenario helfen würde, aber es lohnt sich, es anzuschauen.

Ich habe ein Beispiel dafür hier: https://github.com/DeborahK/MovieHunter-routing

0

Während dieses Problem auf jeden Fall ein Problem mit meinem Auth Muster angegeben ist, wollte ich meine Ergebnisse hier für jedermann lassen, die auf diese Frage stolpert.

Das Problem ist, wie angular behandelt ngIf. Komponenten innerhalb von ngIf werden immer "initialisiert", unabhängig davon, ob sie angezeigt werden. Um dieses Verhalten zu verhindern, verwenden Sie stattdessen Vorlagen.

Siehe Angular4 ng-content gets built when ngIf is false

aber sagen, dass auch mit Vorlagen meiner ursprünglichen Auth Lösung nicht, weil nicht funktioniert kann ich nicht nisten eine <router-outlet> in eine Vorlage. Die richtige Lösung ist dann, die Logik zu ändern und Routenwächter zu verwenden, wie DeborahK vorschlägt.

Verwandte Themen