我无法理解 ngOnInit
和 ngAfterViewInit
之间的区别。
我发现它们之间的唯一区别是 @ViewChild
。根据下面的代码,它们中的elementRef.nativeElement
是相同的。
我们应该使用ngAfterViewInit
什么场景?
@Component({
selector: 'my-child-view',
template: `
<div id="my-child-view-id">{{hero}}</div>
`
})
export class ChildViewComponent {
@Input() hero: string = 'Jack';
}
//////////////////////
@Component({
selector: 'after-view',
template: `
<div id="after-view-id">-- child view begins --</div>
<my-child-view [hero]="heroName"></my-child-view>
<div>-- child view ends --</div>`
+ `
<p *ngIf="comment" class="comment">
{{comment}}
</p>
`
})
export class AfterViewComponent implements AfterViewInit, OnInit {
private prevHero = '';
public heroName = 'Tom';
public comment = '';
// Query for a VIEW child of type `ChildViewComponent`
@ViewChild(ChildViewComponent) viewChild: ChildViewComponent;
constructor(private logger: LoggerService, private elementRef: ElementRef) {
}
ngOnInit() {
console.log('OnInit');
console.log(this.elementRef.nativeElement.querySelector('#my-child-view-id'));
console.log(this.elementRef.nativeElement.querySelector('#after-view-id'));
console.log(this.viewChild);
console.log(this.elementRef.nativeElement.querySelector('p'));
}
ngAfterViewInit() {
console.log('AfterViewInit');
console.log(this.elementRef.nativeElement.querySelector('#my-child-view-id'));
console.log(this.elementRef.nativeElement.querySelector('#after-view-id'));
console.log(this.viewChild);
console.log(this.elementRef.nativeElement.querySelector('p'));
}
}
在第一次调用 ngOnChanges()
之后调用 ngOnInit()
。每次更改检测更新输入时都会调用 ngOnChanges()
。
ngAfterViewInit()
在最初呈现视图后调用。这就是 @ViewChild()
依赖它的原因。在呈现之前,您无法访问视图成员。
ngOnInit()
在第一次检查指令的数据绑定属性之后,并且在检查其任何子项之前立即调用。当指令被实例化时,它只被调用一次。
ngAfterViewInit()
在创建组件视图及其子视图后调用。它是一个生命周期钩子,在组件的视图完全初始化后调用。
内容是作为孩子传递的。 View 是当前组件的模板。
视图在内容之前初始化,因此 ngAfterViewInit()
在 ngAfterContentInit()
之前被调用。
** 第一次检查子指令(或组件)的绑定时调用 ngAfterViewInit()
。因此,它非常适合使用 Angular 2 组件访问和操作 DOM。正如前面提到的@Günter Zöchbauer 是正确的 @ViewChild()
因此在其中运行良好。
例子:
@Component({
selector: 'widget-three',
template: `<input #input1 type="text">`
})
export class WidgetThree{
@ViewChild('input1') input1;
constructor(private renderer:Renderer){}
ngAfterViewInit(){
this.renderer.invokeElementMethod(
this.input1.nativeElement,
'focus',
[]
)
}
}
display: hidden
,它会一直渲染,但在屏幕上不可见。但是,如果您使用浏览器开发工具调查 DOM,您将能够看到标记。ViewChild
(vc) 在onNgInit
上可用? plnkr.co/edit/AzhRe6bjnuPLKJWEJGwp?p=preview,你能解释一下吗?ngOnInit
中已提供静态添加的元素。如果您有由*ngFor
从数据传递到@Input
呈现的内容,则此内容在ngOnInit
中尚不可用