问题
I'm using angular 2 rc1 and the new router @angular/router
In app component I have a nav section and router outlet
<nav>
<a *ngIf="auth?.userName == null" [routerLink]="['/login']">Login</a>
<a *ngIf="auth?.userName != null" (click)="logout()">Logout</a>
{{auth?.userName}}
</nav>
<router-outlet></router-outlet>
I inject a loginService into app component and subscribe to an event in ngOnInit
ngOnInit() {
this.loginService.loginSuccess.subscribe(this.loginSuccess);
}
ngOnDestroy() {
this.loginService.loginSuccess.unsubscribe();
}
private loginSuccess(res: IAuthResponse) {
this.auth = res;
}
when I navigate to my '/login' route page/component my loginService is inject and loginService defines an event
@Output() loginSuccess = new EventEmitter<IAuthResponse>();
and after successful login in my service, the login service raises the event
this.loginSuccess.next(response);
I'm able to set a breakpoint in app component on the subscribed loginSucess and the data is passed along, however 'this' is undefined.
private loginSuccess(res: IAuthResponse) {
this.auth = res; //this is undefind
}
how can I update the app component from events that are triggerd from services used in components that are hosted in the router outlet
回答1:
Not sure what you mean by "and the data is passed".
@Output() loginSuccess = new EventEmitter<IAuthResponse>();
in the component added by the router (LoginComponent) doesn't do anything.
@Input() and @Output() in routed components are not supported.
Just inject LoginService to the routed component and emit the event using an observable in the login component.
@Injectable()
export class LoginService {
changes:BehaviorSubject = new BehaviorSubject(false);
}
export class LoginComponent {
constructor(private loginService:LoginService) {}
onLogin() {
this.loginService.changes.next(true);
}
}
export class NavComponent {
constructor(private loginService:LoginService) {}
onLogin() {
this.loginService.changes.subscribe(status => this.isLoggedIn = status);
}
}
回答2:
This looks like it could be the solution to my problem: passing events from child to parent that uses router-outlet, however it looks like RC1 has changed how BehaviorSubject works. Using the method above:
changes:BehaviorSubject = new BehaviorSubject(false);
gives an error saying BehaviorSubject needs a type declaration, so I tried both
changes:BehaviorSubject<boolean> = new BehaviorSubject(false);
as well as
changes:BehaviorSubject<any> = new BehaviorSubject(false);
and it compiles fine, but when running the app, it gives a non-descriptive error of:
zone.js:323 SyntaxError: Unexpected token <
Evaluating http://localhost:3000/node_modules/rxjs/index.js
Error loading http://localhost:3000/app/main.js
at SystemJSLoader.__exec
(http://localhost:3000/node_modules/systemjs/dist/system.src.js:1395:16)
at entry.execute
I'm assuming something has changed with rxjs and BehaviorSubject
来源:https://stackoverflow.com/questions/37192619/angular-2-update-app-component-from-router-outlet-component