/ / Angular2 - właściwość dostawcy „watch” w wielu komponentach - kątowa, obserwowalna, emiter zdarzeń

Angular2 - właściwość dostawcy „obserwuj” w wielu komponentach - kątowa, obserwowalna, nadawca zdarzeń

Pochodzę ze środowiska NG1 i obecnie jestemtworzenie aplikacji NG2 ze wszystkimi dostępnymi funkcjami. Przed zapytaniem badałem pytania dotyczące google i stackoverflow, ale bez powodzenia, ponieważ kąt 2 poruszał się tak szybko z architekturą API i większość odpowiedzi jest nieaktualna.

Mój przypadek: Mam dostawcę (usługę) Auth z użytkownikiem właściwości, chciałbym obserwować użytkownika i reagować na wiele elementów (pasek nawigacyjny, pasek boczny itp.)

Co próbowałem:

@Injectable();
export class Auth {

private user;
authorized: EventEmitter<boolean>;

constructor(public router:Router){
this.authorized = new EventEmitter<boolean>();
}

login(user, token):void{
localStorage.setItem("jwt", token);
this.user = _.assign(user);

this.authorized.emit(<boolean>true);
this.router.parent.navigateByUrl("/");
}
}


/***************/
@Component({...})
export class NavComponent {

public isAuthroized: boolean = false;

constructor(Auth:Auth){
Auth.authorized
.subscribe((data) => this.onUserChanged(data));
}

onUserChanged(user){
alert("USER:" + user.email);
this.isAuthroized = true;
}
}

/****************/
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
ELEMENT_PROBE_PROVIDERS,
HTTP_PROVIDERS,
MapLoader,
Auth
])

Ale bez powodzenia. Czy powinienem użyć Observable EventEmitter, czy może istnieje inne prawidłowe podejście do obsługi tej sprawy? W NG1 byłoby to tak proste, jak ustawienie $ watch na nieruchomości usługi. Dzięki!

EDYTOWAĆ: Dodałem nową metodę do usługi Auth:

...
userUpdated: EventEmitter<boolean>;

constructor(public router:Router){
this.userUpdated = new EventEmitter<any>();
}

...

logout(returnUrl?: string): void{
delete this.user;
localStorage.removeItem("jwt");
this.userUpdated.emit(undefined);

if(!_.isEmpty(returnUrl)){
this.router.parent.navigateByUrl(returnUrl);
}

}

A teraz wywoływane jest zdarzenie, dlaczego to działa na wylogowanie, a nie na logowanie?

EDYCJA 2:

export class LoginPageComponent {
error: string;

constructor(public http: Http, public router: Router, public Auth:Auth){
}

login(event, email, password){
...
this.http.post("/api/login", loginModel, {headers: headers})
.map((res) => res.json())
.subscribe((res: any) => {
this.Auth.login(res.user, res.ADM_TOKEN);
}, (error) => this.error = error._body);
}

}

ZDECYDOWANY

Głupi błąd… Zostawiłem NavComponent w tablicy dostawców [Auth] .. więc był to inny obiekt niż globalne Auth .. przepraszam! Mam nadzieję, że ten problem pomoże komuś nowemu w Angular2. Dzięki za twój wysiłek.

Odpowiedzi:

1 dla odpowiedzi № 1

Zakładam, że dodajesz Auth jako dostawca każdego komponentu. Spowoduje to utworzenie nowej instancji klasy dla każdego komponentu. Dodaj tylko w bootstrap(AppComponent, providers: [...]) lub tylko na AppComponent.


1 dla odpowiedzi nr 2

Możesz zauważyć, że w Angular nie ma funkcji oglądania, ponieważ jest on teraz zarządzany przez Strefy.

Aby powiadomić inne komponenty, możesz dodać kolejny EventEmitter w twoim Auth usługa dla userUpdated zdarzenie. Składniki, które mają być powiadamiane, mogą zarejestrować się na tym emiterze.

@Injectable();
export class Auth {
private user;
authorized: EventEmitter<boolean>;
userUpdated: EventEmitter<boolean>;

constructor(public router:Router){
this.authorized = new EventEmitter<boolean>();
this.userUpdated = new EventEmitter<boolean>();
}

login(user, token):void{
localStorage.setItem("jwt", token);
this.user = _.assign(user);

this.authorized.emit(<boolean>true);
this.userUpdated.emit(this.user);
this.router.parent.navigateByUrl("/");
}
}

Komponenty mogą zarejestrować się na to wydarzenie:

@Component({...})
export class NavComponent {
(...)
constructor(Auth:Auth){
Auth.userUpdated
.subscribe((data) => this.onUserChanged(data));
}
}

Możesz także podać użytkownika podczas wysyłania authorized zdarzenie:

  login(user, token):void{
localStorage.setItem("jwt", token);
this.user = _.assign(user);

this.authorized.emit(this.user);
this.router.parent.navigateByUrl("/");
}
}

Mam nadzieję, że ci to pomoże, Thierry