[Angular] ViewChild遇上ngIf
當我們有一個child component想要用ViewChild的方法在parent component取得物件,但如果在上面加上ngIf的時候,取得物件的這個動作就會發現根本取不到!!!
在app.component中,使用todo.component,並且加上ngIf作為控制是否顯示
1 | <button (click)="setFlag(!flag)">toggle flag</button> |
在component中,使用ViewChild
的方法並且在setFlag
中印出物件,就可以發現在這個時候是取不到todo這個物件的,就算是用angularJS常用的setTimeout也是一樣
這個問題應該就是變數還沒反應到html,所以導致根本還沒拿到這個物件
1 | export class AppComponent { |
解決方案
但這樣根本不能拿到物件要怎麼往後處理,那這邊有兩個作法
在child component使用事件作為觸發,當物件被ngIf啟動後,就可以拋出事件
1
2
3
4
5
6
7export class TodoComponent implements AfterViewInit {
new EventEmitter(); () onInit =
ngAfterViewInit() {
this.onInit.emit(this);
}
}在parent component收到事件後再去操作ViewChild的物件,就可以正常使用
1
2
3
4<button (click)="setFlag(!flag)">toggle flag</button>
<app-todo (onInit)="trigerTodo($event)" *ngIf="flag">
</app-todo>1
2
3
4
5
6
7
8
9
10
11export class AppComponent {
TodoComponent) todo: TodoComponent; (
setFlag(flag) {
this.flag = flag;
}
trigerTodo(event) {
console.log('component', event);
}
}ViewChild使用setter,當物件被建立時,就可以在裡面進行操作
1
2
3
4
5
6
7
8
9export class AppComponent {
TodoComponent) set todo(content: ViewContainerRef) { (
console.log('setter', content);
}
setFlag(flag) {
this.flag = flag;
}
}
結論
其實在使用ViewChild的時候,使用ngIf其實是不好的應用,但如果真的要用就必須要繞路一下,也要去了解一下各種使用方法,上面的兩個方法,我個人比較喜歡setter的作法,簡單乾淨!
如果有其他作法或想法歡迎來討論喔!!