Angular2学习教程之组件中的DOM操作详解
前言
有时不得不面对一些需要在组件中直接操作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元素后,可以采用类似的方式处理。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家的支持。