環境:
問題的開端:
一開始只是想要把子元件內的一個物件成員丟給父元件去access值,但是子元件的這個物件成員是在自己元件建好了之後送subscribe去跟server要內容。
也就是說子元件的物件內容一開始可能是空的,要等到跟server要到資料的時候才會有內容!因此用了Angular2 官網提供的 Parent interacts with child via local variable是沒用的。
所以只好用ViewChild AfterViewChecked, AfterViewInit的方式來做。
ViewChild: 其實就是透過@ViewChild把子元件包到父元件內然後在透過 @ViewChild的宣告物件來取子元件的內容。
ngAfteViewInit() 是當父元件內的子元件都render好之後會執行,但是因為父元件會在網頁那邊監測childData的值是否有更新而做頁面上值的更換,因此要用setTimeout()的方式讓父元件晚一輪去assign。
然後我用 ngAfterViewChecked() 做檢查子元件的childObj內容變更時幫我把父元件的childData做assign 但是這樣卻運行時出現錯誤。
意思應該是說『顯示改變的內容時它又改變了』,後來換個想法~反正一開始父元件的childData不管子元件childObj內容是server有給或是空的剛宣告而已就在父元件頁面上面render出來,然後在ngAfterViewChecked()內有發現子元件有更新後讓它晚一輪去做assign給父元件的動作就可以運作了!
雖然我不知道我的想法是不是正確,但是的確就沒問題了所以這個就暫時紀錄一下避免我忘記。
修改後的code只是把ngAfterViewInit的setTimeout跟ngAfterViewChecked的assign的對調而已
- Browser : firefox 50.0.2
- angular2 : 2.1.0
- angular-cli: 1.0.0-beta.20-4
- node: 4.4.3
- os : linux x64 Kubuntu 16.04
- 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只是把ngAfterViewInit的setTimeout跟ngAfterViewChecked的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 ); }
留言
張貼留言