受angular.io(父级和子级通过服务进行通信)示例的启发,我实现了一个观察者/可观察模式,以在用户通过身份验证时通知我的导航组件。问题是导航组件只有在用户注销时才会收到通知。
我的身份验证服务看起来像:
export class AuthenticationService {
private isAuthenticatedSource = new Subject<boolean>();
isAuthenticated$ = this.isAuthenticatedSource.asObservable();
constructor(private http : AuthHttp) {}
login(email: string, password: string) {
...
this.isAuthenticatedSource.next(true);
...
}
logout() {
...
this.isAuthenticatedSource.next(false);
...
}
}
我已经确保进行了两次调用(登录和注销),并且没有抛出任何错误。我的导航组件看起来像:
export class NavigationComponent implements OnDestroy, OnInit {
private subscription: Subscription;
isAuthenticated: boolean;
constructor(private authService: AuthenticationService,
private router: Router) {
this.isAuthenticated = authService.isAuthenticated();
}
logout(event) {
event.preventDefault();
this.authService.logout();
this.router.navigate(["Authentication", "Login"]);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnInit() {
this.subscription = this.authService.isAuthenticated$.subscribe(
value => console.log("updated to:", value)
);
}
}
控制台应在登录时记录"Updated to:true",在注销时记录"Update to:false"。问题是它只在注销时显示一条消息。很明显,观察者在登录时没有收到值(true)。希望你能帮助解释为什么会发生这种情况。
更新
登录调用现在包含在下面。当用户提交(登录)表单时,它会从我的LoginComponent
调用。LoginComponent
看起来像:
export class LoginComponent {
public email : string;
public password : string;
public errors : any;
public next : any;
constructor(private authService : AuthenticationService,
private router : Router,
private params : RouteParams) {
// default to navigate to dashboard on successfull login
let next = this.params.get("next") || "/Dashboard";
this.next = [next];
}
login(event) {
event.preventDefault();
this.authService.login(this.email, this.password)
.subscribe(
data => this.router.navigate(this.next),
errors => this.errors = errors);
}
}
相应的模板有一个登录调用:<form (submit)="login($event)">
。登录名不会在应用程序的其他位置调用。
我不知道您在哪里调用了login。然而,我已经创建了一个示例,它显示在UI订阅之前调用服务登录会重现您的观察结果,即UI没有更新。请参阅AppComponent构造函数中的authService.login()调用对UI没有影响。这是因为订阅稍后发生在ngOnInit中。希望这是有用的。
http://plnkr.co/edit/fteTLPCJUucCVKdVzJuP
export class AppComponent implements OnDestroy, OnInit {
@Output subscribe: string;
private subscription: Subscription;
private authService: AuthenticationService;
constructor(private authService: AuthenticationService) {
this.subscribe = 'not set';
this.authService = authService;
authService.login('john', 'password'); // has no affect on UI since login happens before subscribe in ngOnInit
}
login() {
this.authService.login('john', 'password');
}
logout() {
this.authService.logout();
}
ngOnInit() {
this.subscription = this.authService.isAuthenticated$.subscribe(
//value => console.log("updated to:", value)
value => this.subscribe = '' + value;
);
}
}
我不能确切地确定它为什么有效,但将isAuthenticatedSource
设置为静态变量可以解决问题。必须进行更多的研究才能理解原因。感谢您的反馈。