@ViewChild的用法
@ViewChild 获取的是单个模板元素,类型是ElementRef
@ViewChild 获取组件在最下面有介绍
@ViewChild('test') test: ElementRef;
ngAfterViewInit(): void {
this.rd2.setStyle(this.test.nativeElement, 'background', 'red');
}
在ngOninit()中打印@ViewChild或@ViewChildren,有时能打印出来,有时候打印不出来,所以操作dom的时候在ngAfterViewInit()方法里
@ViewChildren用法
@ViewChildren 获取的是多个模板元素,类型是QueryList
@ViewChildren('block') blocks: QueryList<ElementRef>;
ngAfterViewInit(): void {
console.log('ngAfterViewInit中的blocks', this.blocks);
this.blocks.forEach(item => {
this.rd2.setStyle(item.nativeElement, 'border', '3px solid yellow');
});
}
详细代码
image-slider.component.html
<div class="test" #test>
<div class="block" #block *ngFor="let item of data">
{{item.title}}
</div>
</div>
image-slider.component.ts
import { Component, ElementRef, Input, OnInit, QueryList, Renderer2, ViewChild, ViewChildren } from '@angular/core';
// angular8后需要写{ static: true },我用的angular7写这个报错了
// @ViewChild('imageSlider', { static: true }) imgSlider: ElementRef;
@ViewChild('test') test: ElementRef;
@ViewChildren('block') blocks: QueryList<ElementRef>;
data = [{
name: 'wj',
title: '我是测试1'
}, {
name: 'wj',
title: '我是测试2'
}, {
name: 'wj',
title: '我是测试3'
}, {
name: 'wj',
title: '我是测试4'
}];
constructor(private rd2: Renderer2) { }
ngOnInit() {
console.log('ngOnInit中test', this.test); // 打印出来的是个包装节点
console.log('ngOnInit中test', this.test.nativeElement); // 打印出来的是test节点
console.log('ngOnInit中的blocks', this.blocks); // undefined
}
ngAfterViewInit(): void {
// 可以直接操作dom,但是不安全,比如用户可以注入代码时可能会引起SSRH注入攻击
// 比如这个实现了直接清空test中的元素
// this.test.nativeElement.innerHTML = '';
// 在angular中有更安全的操作dom方法 render2
// 先在constructor(private rd2: Renderer2) 声明Renderer2
// 设置test背景色为
this.rd2.setStyle(this.test.nativeElement, 'background', 'red');
// 在ngAfterViewInit()中打印blocks是肯定可以的,是安全的,在ngOnInit()中可能就打印不出来
console.log('ngAfterViewInit中的blocks', this.blocks);
this.blocks.forEach(item => {
this.rd2.setStyle(item.nativeElement, 'border', '3px solid yellow');
});
}
@ViewChild打印出来的内容
@ViewChildren打印出来的内容
@ViewChild引用组件
ImageSliderComponent 是一个完整的组件,在app.component.html中被引用
app.component.html
<app-image-slider [sliders]="imageSliders"> </app-image-slider>
app.component.ts
import { Component, ViewChild, Renderer2 } from '@angular/core';
import { TopMenu, ImageSlider, ImageSliderComponent } from './components';
@ViewChild(ImageSliderComponent) imgComponent: ImageSliderComponent;
constructor(private rd2: Renderer2) { }
ngAfterViewInit(): void {
console.log('imgComponent', this.imgComponent);
// 根据打印出来的内容修改各个属性值
this.rd2.setStyle(this.imgComponent.imgSlider.nativeElement, 'border', '10px solid green');
this.imgComponent.data = [];
}