而不是注入ElementRef并从那里使用querySelector或类似的方法,可以使用声明式的方式来直接访问视图中的元素:
<input #myname>
@ViewChild('myname') input;
元素
ngAfterViewInit() {
console.log(this.input.nativeElement.value);
}
StackBlitz例子
@ViewChild()支持指令或组件类型作为参数,或模板变量的名称(字符串)。
@ViewChildren()还支持以逗号分隔的名称列表(目前不允许@ViewChildren('var1,var2,var3'))。
@ContentChild()和@ContentChildren()做同样的事情,但在轻DOM中(<ng-content>投影元素)。
的后代
@ContentChildren()是唯一一个允许查询后代的
@ContentChildren(SomeTypeOrVarName, {descendants: true}) someField;
{descendants: true}应该是默认值,但在2.0.0 final中不存在,它被认为是一个bug
这在2.0.1中被修复
read
如果有组件和指令,read参数允许指定应该返回哪个实例。
例如,动态创建的组件需要ViewContainerRef,而不是默认的ElementRef
@ViewChild('myname', { read: ViewContainerRef }) target;
订阅的变化
尽管视图子函数只在调用ngAfterViewInit()时设置,而内容子函数只在调用ngAfterContentInit()时设置,如果你想订阅查询结果的更改,应该在ngOnInit()中完成。
https://github.com/angular/angular/issues/9689#issuecomment-229247134
@ViewChildren(SomeType) viewChildren;
@ContentChildren(SomeType) contentChildren;
ngOnInit() {
this.viewChildren.changes.subscribe(changes => console.log(changes));
this.contentChildren.changes.subscribe(changes => console.log(changes));
}
直接DOM访问
只能查询DOM元素,不能查询组件或指令实例:
export class MyComponent {
constructor(private elRef:ElementRef) {}
ngAfterViewInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
// for transcluded content
ngAfterContentInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
}
获取任意投影内容
参见访问传输的内容