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. linux中sed命令批量修改

    sed命令下批量替换文件内容  格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 -rl 路径` 文件名 -i 表示inplace edit,就地修改文件 ...

  2. 网易云课堂----java视频教程

    http://study.163.com/course/introduction.htm?courseId=1003203062#/courseDetail?tab=1

  3. LINUX磁盘分区

    在学习 Linux 的过程中,安装 Linux 是每一个初学者的第一个门槛.在这个过程中间,最大的困惑莫过于给硬盘进行分区.虽然,现在各种发行版本的 Linux 已经提供了友好的图形交互界面,但是很多 ...

  4. python学习第一次笔记

    python第一次学习记录 python是什么编程语言 变成语言主要从以下几个角度进行分类,编译型和解释型.静态语言和动态语言.强类型定义语言和弱类型定义语言. 1.1编译型与解释性 编译型:一次性将 ...

  5. ul li data-* 数据的读取

    <ul class="questions"> <li> <div class="question">1.您的年龄是?< ...

  6. Arch i3wm

    pacman -S i3-gaps i3blocks i3status dmenu xprofile设置 nano /home/user/,xprofile export LANG=zh_CN.UTF ...

  7. org.springframework.beans.factory.BeanCreationException 解决异常错误

    一月 18, 2017 10:18:51 上午 org.apache.coyote.http11.Http11Protocol initINFO: Initializing Coyote HTTP/1 ...

  8. jsonModel使用

    流弊的JSON数据模型框架 https://github.com/jsonmodel/jsonmodel 版本 1.3.0 如果你喜欢JSONModel,并且使用了它,请你: star一下 给我一些反 ...

  9. 阿里云ecs使用补充说明

    前置文章:http://www.cnblogs.com/newbob/articles/5400495.html 阿里云ecs使用心得的一些个人补充部分 一.在yum安装node/npm的过程中出现的 ...

  10. 关于html2canvas跨域设置

    最近在做js生成图片的功能,因为有的商户logo图片在阿里云oss存储的,所以遇到了跨域的问题.跨域的话可以在服务器端设置header, 跨域的话目前的解决方案是服务端设置,Access-Contro ...