Angular2 AfterViewInit , AfterViewChecked 把子元件內的物件丟給父元件的問題

環境:


  1. Browser :  firefox  50.0.2
  2. angular2 :  2.1.0
  3. angular-cli: 1.0.0-beta.20-4
  4. node: 4.4.3
  5. os : linux x64 Kubuntu 16.04
  6. Rest Api Server Django 1.9 + django restframework 3.4.7 

問題的開端:
一開始只是想要把子元件內的一個物件成員丟給父元件去access值,但是子元件的這個物件成員是在自己元件建好了之後送subscribe去跟server要內容
也就是說子元件的物件內容一開始可能是空的,要等到跟server要到資料的時候才會有內容!因此用了Angular2 官網提供的  Parent interacts with child via local variable是沒用的。
所以只好用ViewChild AfterViewChecked, AfterViewInit的方式來做。

ViewChild: 其實就是透過@ViewChild把子元件包到父元件內然後在透過 @ViewChild的宣告物件來取子元件的內容。
export class PhysiologicalComponent implements OnInit, AfterViewChecked, AfterViewInit {
    @Input() userID: number;

    @ViewChild( ChildComponent ) childComp: ChildComponent;

    private childData: ChildObject;
    private userData: MyObject;

    constructor(
        private getInfo: GetService,
    ) { }

    ngOnInit() {
        this.getUserData(this.userID);
    }

    ngAfterViewInit() {
         setTimeout(() => this.childData = this.childComponent.childObj, 0);
    }

    ngAfterViewChecked() {
        if ( this.childData !== this.childComponent.childObj) {
           this.childData = this.childComponent.childObj;
        }
    }

    getUserData( userID ) {
        this.getInfo.getUserInfo( userID ).subscribe(
            (data) => this.userData = data,
            (error) => this.errorMsg = error
        );
    }
這邊運行會有問題!!按照angular2 parent-to-view-child 官網說明是說:
ngAfteViewInit()當父元件內的子元件都render好之後會執行,但是因為父元件會在網頁那邊監測childData的值是否有更新而做頁面上值的更換,因此要用setTimeout()的方式讓父元件晚一輪去assign。

然後我用 ngAfterViewChecked() 做檢查子元件的childObj內容變更時幫我把父元件的childData做assign 但是這樣卻運行時出現錯誤。



 意思應該是說『顯示改變的內容時它又改變了』,後來換個想法~反正一開始父元件的childData不管子元件childObj內容是server有給或是空的剛宣告而已就在父元件頁面上面render出來,然後在ngAfterViewChecked()內有發現子元件有更新後讓它晚一輪去做assign給父元件的動作就可以運作了!
雖然我不知道我的想法是不是正確,但是的確就沒問題了所以這個就暫時紀錄一下避免我忘記。
修改後的code只是把ngAfterViewInitsetTimeoutngAfterViewChecked的assign的對調而已

export class PhysiologicalComponent implements OnInit, AfterViewChecked, AfterViewInit {
    @Input() userID: number;

    @ViewChild( ChildComponent ) childComp: ChildComponent;

    private childData: ChildObject;
    private userData: MyObject;

    constructor(
        private getInfo: GetService,
    ) { }

    ngOnInit() {
        this.getUserData(this.userID);
    }

    ngAfterViewInit() {
         this.childData = this.childComponent.childObj;
    }

    ngAfterViewChecked() {
        if ( this.childData !== this.childComponent.childObj) {
           setTimeout(() => this.childData = this.childComponent.childObj, 0);
        }
    }

    getUserData( userID ) {
        this.getInfo.getUserInfo( userID ).subscribe(
            (data) => this.userData = data,
            (error) => this.errorMsg = error
        );
    }

留言