Angular2视图操作之ViewChildViewChildren
2019獨角獸企業(yè)重金招聘Python工程師標準>>>
熟悉Angular1.X版本的同學應該知道,Angular1.X在指令中的link函數(shù)中提供了element參數(shù),讓我們可以對元素的原生dom進行獲取和操作,在新版本的Angular中,則以decorator的形式,提供了ViewChild,ViewChildren,以及對應的ContentChild和ContentChildren讓我們可以獲取元素的dom對象,本文講解較為常用的ViewChild和ViewChildren這兩個decorator
注意:使用時需要從@angular/core中引入ViewChild和ViewChildren
ViewChild:
ViewChild可以獲取到當前組件視圖中的單個元素,獲取方式有兩種:
第一種(通過模板引用變量):
<main #mychild><!-- my html content --> </main> @ViewChild('mychild') myChild : ElementRefconstructor() { }ngAfterViewInit() {console.log(this.myChild)}第二種(直接指定組件類):
<my-child></my-child> @Component({selector: 'my-child',templateUrl: './xxxxx.html'}) class ChildComponent {constructor() { } } @ViewChild() myChild : ChildComponent;ngAfterViewInit() {console.log(this.myChild)}這兩種方式有何區(qū)別呢?
區(qū)別在于,第一種方式取得的mychild變量是經(jīng)過包裝的,他是一個ElementRef類,其中包含了nativeElement這個屬性,這個屬性的值就相當于通過原生dom操作取得的element。打印結果如下圖:
而如果通過第二種方式,我們需要為組件類注入ElementRef,才能夠取得nativeElement,如下:
//先引入ElementRef //import {ElementRef} from '@angular/core'; @Component({selector: 'my-child',templateUrl: './xxxxx.html'}) class ChildComponent {constructor(public ele: ElementRef) { } }注意,為ChildComponent實例化ElementRef時,需要用public標識符,private的話會導致外部無法取得該ele變量(那你就得專門為其實現(xiàn)一個get方法)
這時,我們就能通過this.mychild.ele.nativeElement來取得其DOM元素了
ViewChildren:
?對應的,ViewChildren,顧名思義是可以獲得一個視圖集合,它是一個類數(shù)組的形式,使用方式與ViewChild相似,但需要以QueryList的形式存在:
@ViewChildren(ChildComponent) myChild : QueryList<ChildComponent>;ngAfterViewInit() {console.log(this.myChild) }QueryList是個什么概念?
我們看看官方文檔的解釋:
我看不懂英文,總的來說就是一個結果集,這個結果集在你的Angular應用更新完成時也隨之更新,
但里面的結果是不可以直接訪問和修改的(很合理)。
我們先來看看打印出來的ViewChildren實例長啥樣:
可以發(fā)現(xiàn)我們想要的取得的結果--(_results)屬性,然而這個_results屬性是private的,我們無法直接取得(經(jīng)實踐可以通過mychild['_results']的方法來獲取,但這也已經(jīng)超出了ts的范圍,也是不安全的做法,應該杜絕),但我們有兩種方式可以遍歷這個_results數(shù)組:
第一是通過mychild.forEach()方法,第二是先調用QueryList原型中的toArray()方法,接著再用數(shù)組的方式進行處理
監(jiān)聽視圖變化:
假設我們有一個由多個my-child組成列表,它可以添加或移除my-child組件,我們希望在my-child集合被改動時都做出回應,此時Observable就派上用場了,QueryList為我們提供了一個changes的Observable:
我們只需要訂閱它就可以完成這個需求了:
this.mychild.changes.subscribe((data)=>{// do something})?
細節(jié):
為何是ngAfterViewInit?
注意到我們獲取mychild都是在ngAfterViewInit的生命周期鉤子函數(shù)中進行的(生命周期的流程詳見https://www.angular.cn/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges)
這是因為mychild是在ngAfterViewInit完成后才能獲取到值,所以也可以在ngAfterViewChecked中獲取,但前者是最快能獲取到的地方,所以在ngAfterViewInit之前的階段,比如ngOnInit,ngOnChanges都是無法獲取到的
還有其他細節(jié)?歡迎評論補充,我會盡量完善。
轉載于:https://my.oschina.net/u/2342955/blog/882473
總結
以上是生活随笔為你收集整理的Angular2视图操作之ViewChildViewChildren的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle数据库部署
- 下一篇: Java基础入门(一):Java里面的时