我有点困惑。我以为我基本上了解了 angular 组件的生命周期,但后来我遇到了一个有趣的案例,其中组件的 @Input 未定义。
在这种情况下,我的应用程序有两个实例。给定的组件:LogoutWarning在注销挂起时显示,然后用户可以刷新登录令牌并继续。这很好用。
该实例在第一个应用程序更新登录令牌时出现,并隐藏显示LogoutWarning组件。在这个第一个应用程序中一切都很好。
第二个应用程序也显示了LogoutWarning组件,因为它检测到登录令牌将要过期并显示LogoutWarning modal,然后它注意到登录令牌已更新并调用 LogoutWarning.cancel() 以隐藏该模式。在这种情况下, this.logoutWarningModal.hide() 会爆炸,因为 this.logoutWarningModal 是UNDEFINED,即使生命周期 ngAfterViewInit() 显示 this.logoutWarningModal 已定义。
在这一点上,我感到非常惊讶。如果我只是检查 this.logoutWarningModal 是未定义的,而不是调用 this.logoutWarningModal.hide() 一切正常。但是为什么 this.logoutWarningModal 在这里未定义???
LoutWarning组件的代码很简单:
@Component({
selector: 'logoutWarning',
template: `
<div bsModal #logoutWarning="bs-modal" [config]="{ show: true }" class="modal fade" tabindex="-1" role="dialog"
aria-labelledby="new application version avaliable" aria-hidden="true" (onHidden)="hidden()">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<div class="app_header">
<div class="app_icon"><img src="assets/images/tracker_hi_res_512.gif"></div>
<div class="app_name">Tracker</div>
</div>
</div>
<div class="modal-body center-message">
<span class="bold">You will be logged out in </span>
<span><strong>{{minutes | async}}</strong> minutes!</span>
</div>
<div class="modal-footer">
<button class="btn btn-primary" (click)="ok()">Stay Logged In</button>
</div>
</div>
</div>
</div>
`
})
export class LogoutWarning implements OnInit {
@ViewChild('logoutWarning') public logoutWarningModal: ModalDirective;
@Input() minutes: string;
constructor(private userCondition: UserCondition, private broadcaster: BroadCaster, private versionS: Version, private auth: AuthService) {
}
public ok(): void {
this.auth.renewLogin(this.userCondition, this.userCondition.minutesDurationUntilLogout.getValue());
this.logoutWarningModal.hide();
}
public cancel() {
if (this.userCondition.bShowLogoutWarning) {
this.logoutWarningModal.hide();
}
}
public hidden() {
// reset the state of the dialog so that it can be reshown.
this.userCondition.bShowLogoutWarning = false;
this.logoutWarningModal.show();
}
public ngOnInit() {
console.log('ngOnInit()');
console.log('this:', this, this.logoutWarningModal);
}
}
Run Code Online (Sandbox Code Playgroud)
并且当 userCondtion.bShowLogoutWarning 为 true 时显示该组件并显示在我的主应用程序中。html的相关部分是:
<logoutWarning *ngIf="userCondition.bShowLogoutWarning" [minutes]="userCondition.minutesUntilLogout"></logoutWarning>
Run Code Online (Sandbox Code Playgroud)
两个应用程序日志:
ngOnInit() logoutWarning.component.ts?f8b4:55
this: LogoutWarning {userCondition: UserCondition, broadcaster: BroadCaster, versionS: Version, auth: AuthService, logoutWarningModal: ModalDirective, …}
ModalDirective {onShow: EventEmitter, onShown: EventEmitter, onHide: EventEmitter, onHidden: EventEmitter, isAnimated: true, …}
userCondition.service.ts?0111:164
Run Code Online (Sandbox Code Playgroud)
然后在第一个应用程序更新登录令牌后,第二个应用程序显示:
this: LogoutWarning {userCondition: UserCondition, broadcaster: BroadCaster, versionS: Version, auth: AuthService} undefined
Run Code Online (Sandbox Code Playgroud)
this.logoutWarningModal 未定义的地方!
感谢您的洞察力!
@ViewChild 将返回undefined直到它被初始化,在 OnInit() 中就是这种情况。改为在 AfterViewInit() 中检查它:
ngAfterViewInit() {
console.log('ngAfterViewInit()');
console.log('this:', this, this.logoutWarningModal);
// this will returns the object
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3241 次 |
| 最近记录: |