在Angular中,我们可以在当前模板的任何地方使用模板引用变量
- 引用模板元素
<div #helloDiv>
你好
</div>
//#后面是给模板或者DOM元素起一个引用名字,以便可以在组件类或木板中进行引用
@ViewChild用来在类中引用模板中的试图节点
可以是Angular组件,也可以是HTML元素
export class AppComponent{
@ViewChild('helloDiv',{static,true}) helloDivRef:ElementRef;
}
static为true说明它并没有配合ngIf在模板中显示
@ViewChild是一个选择器,用来查找要引用的DOM元素或者组件
ElementRef是DOM元素的一个包装类
因为DOM元素不是Angular中的类,所以需要一个包装类以便在Angular中使用和标识其类型
- 通过#直接匹配元素
可以通过
ref-
来代替#
<input #phone placeholder="phone number" />
<button (click)="callPhone(phone.value)">Call</button>
callPhone(value:string){
console.log('callPhone', value);
}
- 模板在组件类中的引用
<app-image-slider [sliders]="imageSliders">
</app-image-slider>
@ViewChild('ImageSliderComponent')
imageSlider:ImageSliderComponent;
如果想引用模板中的Angular组件,@ViewChild中,可以使用引用名,也可以使用组件类型
- 引用多个模板元素
如果仍然用上面的ViewChid,只能取到第一个元素
<img #img *ngFor = "let slider of sliders"
[src] = "slider.imgUrl"
[alt] = "slider.caption"
/>
@ViewChidren('img')
imgs:QueryList<ElementRef>
可以使用@ViewChildren,在@ViewChildren中可以使用引用名,或者使用Angular组件/指令的类型。声明类型为QueryList<?>
ViewChild=>单数 ViewChildren=>复数
- 还可以通过angular的组件或指令进行选择
@ViewChild(ImageSliderComponent) imgSlider:ImageSliderComponent;
- 推荐使用Renderer2操作DOM元素
在构造函数中直接声明,Angular框架帮我们完成注入(开箱即用),默认是单例模式(A、B模块同时注入时,得到的是同一个)
import {Renderer2} from '@angular/core'
constructor(private rd2:Renderer2)
@ViewChildren('img') imgs:QueryList<ElementRef>
ngAterViewInit():void{
this.imgs.forEach(item=>{
this.rd2.setStyle(item.nativeElement,'height','100px')
//设置属性时为this.rd2.setProperty()
})
}
实现过程
- 提供服务
@Injectable()标记为可供注入的服务
- 在模块中声明
providers数组,或import对应模块
ngOnInit(){
const injector = Injector.create({
providers:[
{
provide:Product,
//useClass:Product
useFactory:() => {
return new Product("xxx")
},
deps:[]
//如果还依赖其他的内容,需要在deps数组中提供
},
{
provide:PurchaseOrder,
useClass:PurchaseOrder,
deps:[Product]
}
]
})
}
通常,在使用的时候不需要这么麻烦,只需要放在module.ts中的providers就可以