欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-14 15:17:33
前言 有时不得不面对一些需要在组件中直接操作dom的情况,如我们的组件中存在大量的checkbox,我们想获取到被选中的checkbox,然而这些checkbox是通过循...

前言

有时不得不面对一些需要在组件中直接操作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元素后,可以采用类似的方式处理。

总结

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