2017-09-29 3 views
0

나는 조금 당혹 스럽다. 기본적으로 각 구성 요소의 수명주기를 이해할 수 있다고 생각했지만 흥미로운 경우가 발생했습니다. 구성 요소의 @Input은 정의되지 않았습니다.각 LifecycleHooks 및 @ViewChild는 언제 유효합니까?

이 경우 내 응용 프로그램이 두 개 있습니다 (). 로그 아웃이 보류 중일 때 지정된 구성 요소 : LogoutWarning이 표시되고 사용자는 로그인 토큰을 새로 고치고 계속할 수 있습니다. 그건 잘 작동합니다.

첫 번째 응용 프로그램이 로그인 토큰을 갱신하면 인스턴스가 나타나고 LogoutWarning 구성 요소가 숨겨집니다. 이 첫 번째 애플리케이션에서는 모두 효과적입니다. 이 로그인 토큰이 만료 될 거라고 검출 및 LogoutWarning 모달를 도시 때문에

번째 애플리케이션은 또한 LogoutWarning 구성을 도시하고, 그런 다음 로그인 토큰 리뉴얼 LogoutWarning.cancel을 (호출 된 하였다 통지 그) 모달을 숨 깁니다. 이 경우, lifecyle ngAfterViewInit()가 this.logoutWarningModal이 정의되었음을 나타내지 만 this.logoutWarningModal이 UNDEFINED이기 때문에 this.logoutWarningModal.hide()가 폭발합니다.

나는이 시점에서 매우 놀랐다. 단순히 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 때 표시 사실이고 내 주요 응용 프로그램에 표시됩니다. 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 

곳입니다. logoutWarningModal은 정의되지 않았습니다!

통찰력을 가져 주셔서 감사합니다.

답변

0

@ViewChild는 초기화 될 때까지 undefined을 반환하며 OnInit()의 경우입니다. AfterAfterInit()에서 대신 확인하십시오.

ngAfterViewInit() { 
    console.log('ngAfterViewInit()'); 
    console.log('this:', this, this.logoutWarningModal); 
    // this will returns the object 
} 
+0

정말 이상한 문제는 구성 요소가 이미 초기화되었고 OnInit가 호출되었다는 것입니다. 하지만 내 app.module의 호출은 앱이 부트 스트랩 될 때 지정된 공급자의 초기 LogoutWarning 구성 요소를 호출하는 것처럼 보입니다. 단 하나의 인스턴스 만 생성되고 공유되도록하는 방법이 있습니까? – JoelParke