Angular2学习教程之组件中的DOM操作详解


Posted in Javascript onMay 28, 2017

前言

有时不得不面对一些需要在组件中直接操作DOM的情况,如我们的组件中存在大量的CheckBox,我们想获取到被选中的CheckBox,然而这些CheckBox是通过循环产生的,我们无法给每一个CheckBox指定一个ID,这个时候可以通过操作DOM来实现。angular API中包含有viewChild,contentChild等修饰符,这些修饰符可以返回模板中的DOM元素。

指令中的DOM操作

@Directive({
 selector: 'p'
})
export class TodoDirective{
 constructor(el: ElementRef, renderer: Renderer){
  renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'red');
 }
}

以上声明了一个指令,使用是需要在module中的declarations中声明。该指令的作用是将p元素的backgroundColor设置为red。

-ElementRef是一个允许直接获取DOM元素的一个类,该类包含一个nativeElement属性。当不允许直接操作原生DOM元素时,该属性值为null。

-Renderer该类包含大量可以用来操作DOM原生的方法。

@ViewChild和@ViewChildren

每一个组件都有一个视图模板,通过 template或templateUrl引入。想要获取视图模板中的DOM元素则可以使用@ViewChild和@ViewChildren修饰符。他们可以接受模板变量或元素标签或模板类名来获取DOM节点。@ViewChild返回ElementRef类引用(获取组件时则直接使用组件类名),而@ViewChildren返回QueryList<ElementRef>

//模板内容
<p *ngFor='let item of todos' #name>{{ item.name }}</p>

//组件中获取DOM
@ViewChildren('name')
todoNames: QueryList<ElementRef>;

@ViewChild('name')
todoName: ElementRef;
ngAfterViewInit(){
 this.todoNames.forEach(e=>console.log(e.nativeElement.innerText));
 console.log(this.todoName.nativeElement.innerText);
}

@ViewChild('name')和@ViewChildren('name')通过name模板变量获取p标签DOM节点,可以在ngAfterViewInit声明周期钩子中获取节点信息,当然也可以在其他函数中,只要保证视图完成初始化即可。

QueryList是一个不可变的列表,其存在一个名为changes的Observable变量,因此可以被订阅,结合notifyOnChanges方法,可以实时查看QueryList中变量的变化。调用notifyOnChanges函数后,当组件的输入发生变化时会触发Observable发出新的值,这样当todoNames: QueryList<ElementRef>有更新时,便能通过下面代码查看到变化:

this.todoNames.changes.subscribe(data => data._results.forEach(
 e=>console.log(e.nativeElement.innerText)));
this.todoNames.notifyOnChanges();

@ContentChild和@ContentChildren

看着与@ViewChild和@ViewChildren很相似,但@ContentChild和@ContentChildren是获取组件标签中的内容的,懒得写例子,这里直接贴上angular中文官网的一个例子:

import {Component, ContentChildren, Directive, Input, QueryList} from '@angular/core';
@Directive({selector: 'pane'})
export class Pane {
 @Input() id: string;
}
@Component({
 selector: 'tab',
 template: `
 <div>panes: {{serializedPanes}}</div> 
 `
})
export class Tab {
 @ContentChildren(Pane) panes: QueryList<Pane>;
 get serializedPanes(): string { return this.panes ? this.panes.map(p => p.id).join(', ') : ''; }
}
@Component({
 selector: 'example-app',
 template: `
 <tab>
  <pane id="1"></pane>
  <pane id="2"></pane>
  <pane id="3" *ngIf="shouldShow"></pane>
 </tab>
 <button (click)="show()">Show 3</button>
 `,
})
export class ContentChildrenComp {
 shouldShow = false;
 show() { this.shouldShow = true; }
}

可以看出@ContentChildren(Pane) panes: QueryList<Pane>;获取的是组件Tab中的内容:

<tab>
  <pane id="1"></pane>
  <pane id="2"></pane>
  <pane id="3" *ngIf="shouldShow"></pane>
 </tab>

与@ViewChild类似@ContentChild获取的是第一个Pane指令,获取DOM元素后,可以采用类似的方式处理。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家三水点靠木的支持。

Javascript 相关文章推荐
一个很酷的拖动层的js类,兼容IE及Firefox
Jun 23 Javascript
JS获取父节点方法
Aug 20 Javascript
jquery 学习之二 属性(html()与html(val))
Nov 25 Javascript
读jQuery之十三 添加事件和删除事件的核心方法
Aug 23 Javascript
JS实现根据出生年月计算年龄
Jan 10 Javascript
JS实现超精简的链接列表在固定区域内滚动效果代码
Nov 04 Javascript
Bootstrap表单布局样式代码
May 31 Javascript
jQuery Ajax 上传文件处理方式介绍(推荐)
Jun 30 Javascript
JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
Aug 11 Javascript
浅谈jquery中next与siblings的区别
Oct 27 Javascript
js获取指定时间的前几秒
Apr 05 Javascript
Js参数RSA加密传输之jsencrypt.js的使用
Feb 07 Javascript
Angular2学习教程之ng中变更检测问题详解
May 28 #Javascript
Angular2使用jQuery的方法教程
May 28 #jQuery
Angular.js实现动态加载组件详解
May 28 #Javascript
利用node.js如何搭建一个简易的即时响应服务器
May 28 #Javascript
利用Angular.js编写公共提示模块的方法教程
May 28 #Javascript
Angular2入门教程之模块和组件详解
May 28 #Javascript
关于Angular2 + node接口调试的解决方案
May 28 #Javascript
You might like
php 全局变量范围分析
2009/08/07 PHP
比较strtr, str_replace和preg_replace三个函数的效率
2013/06/26 PHP
PHP实现远程下载文件到本地
2015/05/17 PHP
PHP中PDO的事务处理分析
2016/04/07 PHP
js nextSibling属性和previousSibling属性概述及使用注意
2013/02/16 Javascript
jquery跟js初始化加载的多种方法及区别介绍
2014/04/02 Javascript
javascript 判断整数方法分享
2014/12/16 Javascript
原生js和jQuery写的网页选项卡特效对比
2015/04/27 Javascript
angularjs在ng-repeat中使用ng-model遇到的问题
2016/01/21 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
浅析ES6的八进制与二进制整数字面量
2016/08/30 Javascript
bootstrap table小案例
2016/10/21 Javascript
js获取时间函数及扩展函数的方法
2016/10/30 Javascript
Angularjs使用ng-repeat中$even和$odd属性的注意事项
2016/12/31 Javascript
JS判断Android、iOS或浏览器的多种方法(四种方法)
2017/06/29 Javascript
深入理解Vue router的部分高级用法
2018/08/15 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
2019/04/17 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
nodejs和react实现即时通讯简易聊天室功能
2019/08/21 NodeJs
原生JavaScript实现弹幕组件的示例代码
2020/10/12 Javascript
原生JS运动实现轮播图
2021/01/02 Javascript
前端如何实现动画过渡效果
2021/02/05 Javascript
[01:56]生活中的妖精之七夕特别档
2016/08/09 DOTA
Python smtplib实现发送邮件功能
2018/05/22 Python
Python WSGI的深入理解
2018/08/01 Python
python3 爬取图片的实例代码
2018/11/06 Python
Python imread、newaxis用法详解
2019/11/04 Python
Python3 pywin32模块安装的详细步骤
2020/05/26 Python
Boden美国官网:英伦原创时装品牌
2017/07/03 全球购物
全球地下的服装和态度:Slam Jam
2018/02/04 全球购物
大学生毕业鉴定
2014/01/31 职场文书
会计专业应届生自荐信
2014/02/07 职场文书
《菜园里》教学反思
2014/04/17 职场文书
投标承诺书怎么写
2014/05/24 职场文书
信用卡工作证明模板
2014/09/14 职场文书
Ajax 的初步实现(使用vscode+node.js+express框架)
2021/06/18 Javascript