我有点困惑。我以为我基本上理解了角度组件的生命周期,但是我遇到了一个有趣的案例,其中组件的@Input未定义。
在这种情况下,我有两个应用程序实例。当注销处于挂起状态时,将显示给定组件: LogoutWarning ,然后用户可以刷新登录令牌并继续。这很好。
当第一个应用程序更新登录令牌并且隐藏显示 LogoutWarning 组件时,实例会出现。在第一个申请中一切都很好。
第二个应用程序还显示 LogoutWarning 组件,因为它检测到登录令牌将过期并显示 LogoutWarning模式,然后它会注意到登录令牌已更新并调用LogoutWarning.cancel()来隐藏模态。在这种情况下,this.logoutWarningModal.hide()会爆炸,因为this.logoutWarningModal是 UNDEFINED ,即使lifecyle 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);
}
}
当userCondtion.bShowLogoutWarning为true并在我的主应用程序中显示时显示该组件。 html的相关部分是:
<logoutWarning *ngIf="userCondition.bShowLogoutWarning" [minutes]="userCondition.minutesUntilLogout"></logoutWarning>
两个应用程序都记录:
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
然后在第一个应用程序更新登录令牌后,第二个应用程序显示:
this: LogoutWarning {userCondition: UserCondition, broadcaster: BroadCaster, versionS: Version, auth: AuthService} undefined
其中this.logoutWarningModal是UNDEFINED!
感谢您的见解!
答案 0 :(得分:2)
@ViewChild将返回undefined
直到它被初始化,并且在OnInit()中就是这种情况。请在AfterViewInit()中检查它:
ngAfterViewInit() {
console.log('ngAfterViewInit()');
console.log('this:', this, this.logoutWarningModal);
// this will returns the object
}