【发布时间】:2016-03-27 01:31:54
【问题描述】:
受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)
);
}
}
登录时控制台应记录“更新为:true”,注销时应记录“更新为: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 在应用程序的其他地方不会被调用。
【问题讨论】:
-
您已经可以在构造函数中订阅,如果代码不依赖于正在更新的输入,则无需等待
ngOnInit()。也许该事件在NavigationComponent订阅之前已经发送。我认为您需要BehaviorSubject才能在订阅后立即获得最后一个值。 -
我没有在您的代码中看到对
login的调用 - 您确定要在 订阅主题之后调用它吗? Subject 只会在订阅后向订阅者发送事件 - 你可能想要不同类型的 Subject,也许是BehaviorSubject -
感谢您的反馈。尝试了 BehaviorSubject 并没有改变任何东西。我还将订阅调用移动到构造函数,但情况还是一样。 @tddmonkey 是的,我确定。当用户单击按钮时调用 login - 在 NavigationComponent 订阅主题很久之后。
标签: typescript angular rxjs