我有一个登录/注销的AuthService,检查用户是否已登录并使用angular2-jwt
(例如使用tokenNotExpired()
)。
我仅为此服务创建了一个模块,以便将其用作单例。
现在我检查用户是否已登录,例如:
<p *ngIf="authService.authenticated()">Text</p>
按预期工作。
现在我想要实现的是将此*ngIf
包装到自己的指令中,以便检查用户是否已登录的组件不必注入AuthService。
基本上是这样的:
<p *authenticated>Text</p>
我已经创建了这样的经过身份验证的指令:
@Directive({selector: "[authenticated]"})
export class AuthenticatedDirective {
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private auth: AuthService) {
}
@Input() set authenticated(condition: boolean) {
if (this.auth.authenticated()) {
console.log("IsLoggedIn");
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
console.log("NotLoggedIn");
this.viewContainer.clear();
}
}
}
它基本上是* ngIf指令,只是它没有使用参数。
问题是,只有在加载网站时才会调用它,它不会定期检查this.auth.authenticated()
以查看令牌是否已过期。
如果指令没有收听,那么触发变更检测当然不会做任何事情,因此手动触发(例如,在注销后)它无法正常工作。
我知道你可以&#34;听&#34; (使用host或HostListeners)指令中的事件,但是我无法找到更改检测的事件,我可以使用该事件触发指令以更新&#34;。
所以基本上我的问题是,我怎样才能听取更改检测事件,还是有更好的解决方案来包装这个*ngIf="authService.authenticated()"
?
提前致谢。
更新:
根据@Chrillewoodz的评论,我终于想起了生命周期钩子,特别是提到的DoCheck。
我目前的指令解决方案是:
@Directive({selector: "[authenticated]"})
export class AuthenticatedDirective implements DoCheck {
private isAuthenticated = false;
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private auth: AuthService) {
}
ngDoCheck() {
if (this.isAuthenticated !== this.auth.authenticated()) {
this.isAuthenticated = this.auth.authenticated();
if (this.auth.authenticated()) {
console.log("IsLoggedIn");
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
console.log("NotLoggedIn");
this.viewContainer.clear();
}
}
}
}
答案 0 :(得分:4)
我认为编写指令的方式需要使用像
这样的指令<p *authenticated="isAuthenticated">Text</p>
isAuthenticated
返回true
或false
的位置(无论您是否经过身份验证)
我认为您应该向authService.authenticated()
添加一个可通知的观察点,而不是轮询authService
。
@Directive({selector: "[authenticated]"})
export class AuthenticatedDirective {
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private auth: AuthService) {
auth.isAuthenticated.subscribe(authenticated => {
if (authenticated()) {
console.log("IsLoggedIn");
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
console.log("NotLoggedIn");
this.viewContainer.clear();
}
});
}
}
https://angular.io/docs/ts/latest/cookbook/component-communication.html显示了一些关于如何使用observable创建服务的很好的例子。