Angular8 实战(十六)在模板中引用多个元素

上一章学习了在组件类中通过ViewChild去引用模板中的元素,是通过引用名引用的。但是ViewChild不只可以指定引用名引用,也可以指定组件类型来引用。

@ViewChild

比如引用image-slider组件,那么使用方法如下:


@ViewChild('ImageSliderComponent', { static: true }) imageSlider: ImageSliderComponent;

所以,如果想引用模板中的Angular组件,@ViewChild中,可以使用引用名,也可以使用组件类型。

@ViewChildren

上面说的是单个模板的引用,如果想引用多个模板元素该如何处理呢?
比如,想选中image-slider中所有的轮播图图片,如果继续使用@ViewChild,那么对于相同命名的,ViewChild只会选中ngFor中的第一个元素,并不会选中整个img元素。这就引出了@ViewChildren可以选中整个img数组。


@ViewChildren('img') imgs: QueryList;

所以,可以使用@ViewChildren,在@ViewChildren中可以使用引用名或者使用Angular组件/指令的类型。声明类型为QueryList

打印出imgs看一下效果:


16-1.gif

可以看出这个时候并没有打印出imgs属性,为什么呢?这就用到前面学习的知识了:组件的生命周期。
ngOnInit的时候,视图并没有初始化完成。ngAfterViewInit是视图初始化完成。
再来看一下效果:


16-2.gif

Renderer2

之前讲过,Angular是不推荐直接操作DOM的。那么Angular推荐使用什么呢?
没错,推荐使用Renderer2。
先来看一下用法示例


16-3.gif

那么问题来了,为什么我们要这样用呢?直接写不好吗?
解释一下:如果直接操作DOM,即自己写html节点,可能会造成XSS攻击。比如我们的应用是允许用户自己写一段Html代码传到组件类中,这个时候你不确定用户是否是恶意写入的攻击代码,这其实就属于XSS攻击。
Renderer2是渲染器,默认情况下,Angular会把模板渲染成DOM,同时会检查恶意代码的注入。

总结
@ViewChild用来在类中引用模板中的视图节点,既可以是Angular组件,也可以是HTML元素
在AfterViewInit中可以安全的使用@ViewChild引用的元素
推荐使用Renderer2操作DOM元素

你可能感兴趣的:(Angular8 实战(十六)在模板中引用多个元素)