angular2的ElementRef在组件中获取不到

angular2不推荐操作dom,但是实际应用中不可避免的需要使用到dom操作,怎么操作,官方文档提供了一系列api(ElementRef,ViewContainerRef ,TemplateRef)配合

@ViewChild或@ViewChildren就可以获取到dom元素,但是这个过程中有些文档未提及的坑,本人不小心踩进去,半天才爬出来,因此分享一下。
 首先,需要在ng2的模板中使用 #bannersEL定义一个模板局部变量,如:
<div class="swiper-wrapper" #bannersEL></div>

 接着在模板对应的组件类中,使用组件中元数据@ViewChild来获取模板局部变量的读写权限:

export class DemoComponent implements AfterViewInit  {

@ViewChild("bannersEL") bannersEl: ElementRef; ngAfterViewInit(): void {
console.log(this.bannersEl);
}
}

 其中 @ViewChild("bannersEL") bannersEl: ElementRef 还可以使用如下语法限定局部变量的权限:

 @ViewChild("bannersEL",{read:ElementRef}) bannersEl: ElementRef;

还需要注意点,this.bannersEl 对象获取模板局部变量时机,仅在ngAfterViewInit生命周期之后才有,也就是说在组件构造器,及onint等生命周期时是获取不到的。

然后还有一个最坑人的一点#bannersEL 模板局部变量最好写在html元素的最前面,像上面那样在模板标签中定义模板局部变量,居然会导致组件中获取不到,目前还不知道原因为何,正确写法如下

 <div #bannersEL class="swiper-wrapper">

 但是你以为这样就完了吗,不,还有坑,如果你的模板中用了ngFor指令,并且循环绑定了模板局部变量,如:

 <div #bannersEL class="swiper-slide" *ngFor="let banner of banners;t"></div>

 //--------ts
  @ViewChildren("bannersEL") bannersEl: QueryList<ElementRef>;

  ngAfterViewInit(): void {
   console.log(this.bannersEL.length)
  }
//输出结果是0,而实际上模版最终生成的div是有3个

解决以上问题的办法就是模板代码不动,js中做如下变动:

 ngAfterViewInit(): void {
this.bannersEl.changes.subscribe((list:QueryList<ElementRef>)=>{
if(list.length > 0){
list.forEach( el=>{
el.nativeElement.style.display="none";
});
}
});
}

通过订阅changes来获取循环后得到div对象

angular2的ElementRef在组件中获取不到的更多相关文章

  1. 微信小程序在组件中获取界面上的节点信息wx.createSelectorQuery

    节点信息查询 API 可以用于获取节点属性.样式.在界面上的位置等信息. 最常见的用法是使用这个接口来查询某个节点的当前位置,以及界面的滚动位置. 示例代码: const query = wx.cre ...

  2. 在自定义组件中获取spring底层组件

    要想在自定义组件中获取spring底层的各种组件,只需让自定义组件实现一系列接口即可,这些接口都是Aware的子接口.常见的有: 1. ApplicationContextAware——用于获取IOC ...

  3. vue父组件中获取子组件中的数据

    <FormItem label="上传头像" prop="image"> <uploadImg :width="150" ...

  4. Web项目中获取SpringBean——在非Spring组件中获取SpringBean

    最近在做项目的时候我发现一个问题:Spring的IOC容器不能在Web中被引用(或者说不能被任意地引用).我们在配置文件中让Spring自 动装配,但并没有留住ApplicationContext的实 ...

  5. delphi 从 TWebbrowse组件中获取图片

    在 delphi 中使用 TWebbrowse 组件,虽然效率不如用(idhttp之类)模拟操作效率高.但其难度低,上手快,简单粗暴有效. 从网上搜到的处理此问题的文章大多是 ctrl + c 复制到 ...

  6. 在Vue组件中获取全局的点击事件

    // 定义全局点击函数 Vue.prototype.globalClick = function (callback) { document.getElementById('main').onclic ...

  7. 微信小程序将外部数据从父组件中传入到子组件

    小程序组件开发遇到一个组件内嵌两个组件,而这两个子组件所使用的数据来自于同一个API,如下图所示. 如果这时候两个子组件各自导入同一个接口就会显得多余.另外的办法是由父组件导入接口数据,再从父组件将接 ...

  8. 【ASP.NET Core】在Blazor中获取 HTTP 上下文信息

    今天咱们来扯一下 Blazor 应用程序怎么访问 HttpContext.其实这句话有坑,为了避免大伙伴们掉茅坑,老周直接说明:Blazor 是不能访问 HttpContext 的.哪怕你在服务容器中 ...

  9. Vue3 SFC 和 TSX 方式调用子组件中的函数

    在开发中会遇到这样的需求:获取子组件的引用,并调用子组件中定义的方法.如封装了一个表单组件,在父组件中需要调用这个表单组件的引用,并调用这个表单组件的校验表单函数或重置表单函数.要实现这个功能,首先要 ...

随机推荐

  1. Python机器学习(基础篇---监督学习(线性分类器))

    监督学习经典模型 机器学习中的监督学习模型的任务重点在于,根据已有的经验知识对未知样本的目标/标记进行预测.根据目标预测变量的类型不同,我们把监督学习任务大体分为分类学习与回归预测两类.监督学习任务的 ...

  2. mbstowcs 和ifstream 前为何要setlocale

    最近看公司的一些代码,发现一些地方调用了std::locale::global(locale("")); (c++) 和 setlocale(LC_ALL, "" ...

  3. java第七周----json

    JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于 ...

  4. dos5章

    一.用set命令设置自定义变量 显示.设置或删除 cmd.exe 环境变量. SET [variable=[string]]variable 指定环境变量名.string 指定要指派给变量的一系列字符 ...

  5. scrapy框架修改单个爬虫的配置,包括下载延时,下载超时设置

    在一个框架里面有多个爬虫时,每个爬虫的需求不相同,例如,延时的时间,所以可以在这里配置一下custom_settings = {},大括号里面写需要修改的配置,然后就能把settings里面的配置给覆 ...

  6. 帝国cms中下拉框select的绑定

    在修改数据模型中,将下拉框的表示代码换成下: 将id换成自己的id地址.数据库查询中的classid换成自己创建栏目的id. <select name="diqu" id=& ...

  7. Win32线程——等待另一个线程结束

    转载: https://blog.csdn.net/yss28/article/details/53646627 <Win32多线程程序设计>–Jim Beveridge & Ro ...

  8. 3D数学基础(二)向量

    向量的基本运算包括加法.减法.点乘.叉乘.单位化运算等,而在游戏开发中使用最为广泛的是减法.点乘.叉乘.单位化运算.向量是具有方向和长度的矢量,有2D.3D.4D等的.在游戏开发里面一般使用的是2D和 ...

  9. 利用axure软件实现app中的轮播图功能

    1.首先在axure软件中插入一张手机模型图片并调整为合适大小 2.在需要展示轮播图片位置拖入[动态面板]并且调整大小 拖入后双击动态面板,填入面板名称,并且添加面板状态(此处轮播图为三张,所以有三个 ...

  10. Qt代码吐槽

    擦,代码注释里写这么多“NB!”是要闹哪样!!