亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

獲取模板元素

基本概念

Angular 内置了 ViewChild 和 ViewChildren 装饰器来获取模板中匹配到的元素或指令。
在 ngAfterViewInit 钩子函数中才能够查看获取到的元素或指令。

*ngAfterViewInit:组件视图初始化之后调用。

ViewChild

获取模板中匹配到的第一个元素或指令。

1、获取原生 DOM 元素

通过模板引用变量来获取原生 DOM 元素。

例子:

// app.component.html
<section>
  <p #text>hello</p>
</section>

// app.component.ts
// 引入装饰器 ViewChild 和接口 ElementRef
import { Component, AfterViewInit, ViewChild, ElementRef} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements AfterViewInit {

  // 取到变量 text,类型为 ElementRef
  @ViewChild('text')
  txt!:ElementRef;

  constructor() { }

  // 查看获取到的元素
  ngAfterViewInit(){
    console.log(this.txt.nativeElement.innerHTML);
  }
}

ElementRef 是 Angular 封装的一个用于操作原生 DOM 元素的接口,究其原因,是因为 Angular 本身不局限于只在浏览器上运行(比如还有 web workder 环境,不存在 DOM)。因此,Angular 内置了 ElementRef 隔离开应用层与 DOM 层。如果我们需要直接操作 DOM 元素,可以通过 ElementRef 下的 nativeElement 属性。

2、获取组件及其内部属性

获取组件有两种方式,第一种依然是通过模板引用变量:

例子:

// app.component.html
<section>
  <app-my-component #text></app-my-component>
</section>

// app.component.ts
/// 引入装饰器 ViewChild 和子组件 MyComponentComponent
import { Component, AfterViewInit, ViewChild} from '@angular/core';
import { MyComponentComponent } from './components/my-component/my-component.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements AfterViewInit {

  // 取到变量 text,类型设置为 MyComponentComponent
  @ViewChild('text')
  txt!:MyComponentComponent; // 类型为 any 也可以

  constructor( ) { }

  // 查看获取到的元素
  // welcome 为子组件的属性,可以直接使用
  ngAfterViewInit(){
    console.log(this.txt.welcome);
  }
}

第二种是通过组件类:

// 如果不使用模板引用变量
// 直接引入组件 MyComponentComponent 也可以
// 如下写法:
@ViewChild(MyComponentComponent)
txt!:MyComponentComponent;

3、获取指令

通过模板引用变量来获取 ng-template 指令的内容在《模板引用变量》已经详细介绍过,在此就不再赘述。

设置查询条件

ViewChild 可以选择性设置第二个参数 read,用来增加查询条件。但这个参数不是必需的,因为 Angular 会根据即将返回的类型自动添加查询条件,比如将要返回的是原生 DOM 元素,那么查询类型就是 ElementRef,如果将要返回的是内嵌模板 ng-template,那么查询类型就 TemplateRef,再比如我们上个例子中,将要返回的是子组件将 MyComponentComponent,那么默认的查询类型就是MyComponentComponent

例子:

// html
<section>
  <app-my-component #text></app-my-component>

  <ng-template #name>
    <p>Tom</p>
  </ng-template>

  <p #age>20</p>
</section>

// ts
import { Component, AfterViewInit, ViewChild, ElementRef, TemplateRef } from '@angular/core';

@ViewChild('text',{read: MyComponentComponent})
txt!:MyComponentComponent;

@ViewChild('name',{read:TemplateRef})
name!:TemplateRef<any>;

@ViewChild('age',{read:ElementRef})
age!:ElementRef;

ngAfterViewInit(){
  console.log(this.txt);
  console.log(this.name);
  console.log(this.age);
}

图片描述

上面例子中,不添加查询条件,返回的结果是一样的:

例子:

@ViewChild('text')
txt!:MyComponentComponent;

@ViewChild('name')
name!:TemplateRef<any>;

@ViewChild('age')
age!:ElementRef;

但是,ViewContainerRef 类型不能被 Angular 推断出来,需要手动添加查询条件。

例子:

// html
<section>
  <ng-template #name>
    <p>Tom</p>
  </ng-template>

  <p #age>20</p>
</section>

// ts
import { Component, AfterViewInit, ViewChild, ElementRef, TemplateRef ,ViewContainerRef} from '@angular/core';

@ViewChild('name')
name!:TemplateRef<any>;

@ViewChild('name',{read:ViewContainerRef})
nameActive!:ViewContainerRef;

@ViewChild('age',{read:ViewContainerRef})
age!:ViewContainerRef;

ngAfterViewInit(){
  this.nameActive.createEmbeddedView(this.name);
  this.age.createEmbeddedView(this.name);
}

ViewChildren

获取模板中匹配到的多个元素或指令,返回一个 QueryList 集合。

例子:

// html
<section>
  <app-my-component #text></app-my-component>

  <ng-template #text>
    <p>Tom</p>
  </ng-template>
  
  <p #text>20</p>
</section>

// ts
import { Component, AfterViewInit, ViewChildren, QueryList} from '@angular/core';

@ViewChildren('text')
txt!:QueryList<any>;

ngAfterViewInit(){
  if (this.txt != null && this.txt.length !== 0) {
    this.txt.forEach(el => console.log(el));
  }
}

end

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
Web前端工程師
手記
粉絲
1.4萬
獲贊與收藏
860

關注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消