用于指令更改检测的 Angular2 事件
Angular2 Event for Change detection for Directive
我有一个记录 in/out 的 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()
以查看令牌是否过期。
如果指令不监听它,那么触发变化检测当然不会做任何事情,所以手动触发(例如,在注销后)它不起作用。
我知道您可以 "listen"(使用主机或 HostListeners)指令中的事件,但我找不到用于更改检测的事件,我可以用它触发指令 "update".
所以基本上我的问题是,我如何才能收听更改检测事件或者是否有更好的解决方案来包装这个 *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();
}
}
}
}
我认为你的指令是这样写的,你需要像这样使用你的指令
<p *authenticated="isAuthenticated">Text</p>
其中 isAuthenticated
returns true
或 false
(无论您是否已通过身份验证)
我认为你应该向 authService
添加一个 observable 来通知关于
而不是轮询 authService.authenticated()
@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 展示了一些关于如何使用可观察对象创建服务的很好的示例。
我有一个记录 in/out 的 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()
以查看令牌是否过期。
如果指令不监听它,那么触发变化检测当然不会做任何事情,所以手动触发(例如,在注销后)它不起作用。
我知道您可以 "listen"(使用主机或 HostListeners)指令中的事件,但我找不到用于更改检测的事件,我可以用它触发指令 "update".
所以基本上我的问题是,我如何才能收听更改检测事件或者是否有更好的解决方案来包装这个 *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();
}
}
}
}
我认为你的指令是这样写的,你需要像这样使用你的指令
<p *authenticated="isAuthenticated">Text</p>
其中 isAuthenticated
returns true
或 false
(无论您是否已通过身份验证)
我认为你应该向 authService
添加一个 observable 来通知关于
authService.authenticated()
@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 展示了一些关于如何使用可观察对象创建服务的很好的示例。