2016-02-21 32 views
13

Possiedo un servizio di autenticazione che rende la variabile autenticata uguale a true o false.Angular2 - sottoscrizione a Variazioni delle variabili di servizio

checkAuthentication(){ 
    this._authService.getAuthentication() 
    .subscribe(value => this.authenticated = value); 
} 

Come faccio a eseguire una funzione quando this.authenticated è cambiato il valore? ngOnChanges non sta riprendendo il cambiamento.

risposta

19

Per mantenere authenticated in servizio e condividerlo tra i componenti è possibile utilizzare BehaviorSubject, è value per controllare l'autenticazione in luoghi diversi, ed è subscribe() metodo di reagire al cambiamento ...

class AuthService { 
    public authenticated = new BehaviorSubject(null); 
    getAuthentication() { 
    this._http.get('/authenticate') 
     .map(response => response.json()) 
     .map(json => Boolean(json)) // or whatever check you need... 
     .subscribe((value: boolean) => this.authenticated.next(value)) 
    } 
} 

class Component { 
    constuctor(private _authService: AuthService) { 
    // Only check once even if component is 
    // destroyed and constructed again 
    if (this._authService.authenticated.value === null) 
     this._authService.getAuthentication(); 
    } 

    onSubmit(){ 
    if (!this._authService.authenticated.value) 
     throw new Error("You are authenticated!") 
    } 
} 

Come faccio a eseguire una funzione quando this.authenticated ha cambiato valore?

this._authService.authenticated 
    .subscribe((value: boolean) => console.log(value)) 
+0

Ciao @Sasxa quindi se ho per es. 5 componenti. 'home.component.ts',' footer.component.ts', 'navbar.component.ts',' x.component.ts' e 'user.component.ts'. Supponendo questi 5 componenti, e se voglio verificare l'autenticazione. Dovrò aggiungere inject il seguente: 'costruttore (privato _authService: AuthService) {...}' a tutti i miei 5 componenti. È corretto? e fai un 'ngOnInit' per tutti e 5 i componenti?Hai bisogno di aiuto per capire il concetto di autenticazione Angular2. –

+1

Ci sono molte opzioni/scelte. Tutto dipende da cosa stai facendo. È possibile eseguire l'autenticazione a ogni componente o solo al componente root. È un argomento complesso, dovrai decidere cosa è meglio per la tua app (; – Sasxa

+0

potresti indicarmi discussione/forum/blog/articolo su questo argomento? –

9

Penso che si potrebbe sfruttare la sintassi get/set di dattiloscritto per rilevare quando la vostra proprietà autenticata del vostro servizio viene aggiornato:

private _authenticated:Boolean = false; 
    get authenticated():Boolean { 
     return this._authenticated ; 
    } 
    set authenticated (authenticated Boolean) { 
    // Plugin some processing here 
     this._ authenticated = authenticated; 
    } 

Quando si assegna un valore, il "set autenticato "viene chiamato il blocco. Ad esempio, con tale codice:

this.authenticated = true; 

Vedere questa domanda per maggiori dettagli:

Detto questo si potrebbe anche sfruttare una proprietà EventEmitter nel servizio. Quando la proprietà autenticata viene aggiornata, può essere generato l'evento corrispondente.

export class AuthService { 
    authenticatedChange: Subject<boolean> = new Subject(); 

    constructor() {} 

    emit(authenticated) { 
    this.authenticatedChange.next(authenticated); 
    } 

    subscribe(component, callback) { 
    // set 'this' to component when callback is called 
    return this.authenticatedChange.subscribe(data => { 
     callback(component, data); 
    }); 
    } 
} 

Vedere questo link per maggiori informazioni:

+0

È un buon approccio con cui andare, dato che stai suggerendo di attivare qualche evento mentre si imposta il valore 'autenticato'? impostando il valore manipolando il valore di input fornito per la sua funzione .. –

+0

Ciao Thierry, ho cercato il sito di Angular.io per la documentazione/tutorial su EventEmitter, ma era piuttosto limitato Qualche idea su dove posso trovare un tutorial guidato sull'uso di Angular2 EventEmitter? –

+1

questo è considerato una cattiva pratica, l'approccio consigliato è l'uso di Subject/BehaviorSubject – atsituab

0

Dipende da chi ha bisogno di gestire l'evento. Se è il componente principale, è possibile sfruttare binding di eventi di uscita:

@Output authenticationChange: EventEmitter<Boolean> = new EventEmitter(); 
checkAuthentication(){ 
    this._authService.getAuthentication() 
    .subscribe(value => 
      if(value != this.authenticated) { 
       this.authenticated = value); 
       this.authenticationChange.emit(value); 
     }); 
} 

E nel tuo componente principale:

<directive (authenticationChange)="doSomething()"> 
-2

ho usato un {{ showValue() }} nel modello dei componenti, e nel file .ts ho chiamato la variabile del servizio

showValue() { 
    this.authenticated = this._authService.authenticated; 
    return "dummy" 
} 

Grazie alla connessione a 2 vie della GUI di Angular2, funziona.

Problemi correlati