Cette fois, je vais vous montrer comment utiliser ElementRef dans Angular4. Quelles sont les précautions pour utiliser ElementRef dans Angular4. Voici des cas pratiques. .
Le slogan d'Angular est - "Un framework, plusieurs plates-formes. Convient à la fois aux mobiles et aux ordinateurs de bureau (One framework.Mobile & desktop.)", c'est-à-dire qu'Angular prend en charge le développement d'applications multiplateformes, telles que : des applications Web, des applications Web mobiles, des applications mobiles natives, des applications de bureau natives, etc.
Afin de prendre en charge plusieurs plates-formes, Angular encapsule les différences des différentes plates-formes via une couche d'abstraction et unifie l'interface API. Par exemple, la classe abstraite Renderer et la classe abstraite RootRenderer, etc. De plus, les types de référence suivants sont définis : ElementRef, TemplateRef, ViewRef, ComponentRef. et ViewContainerRef etc. Analysons la classe ElementRef :
L'exploitation directe du DOM dans la couche application entraînera un couplage fort entre la couche application et la couche de rendu, empêchant notre application de s'exécuter dans différents environnements, tels que les travailleurs Web, car dans le Web Dans l'environnement de travail, le DOM ne peut pas être directement manipulé. Les lecteurs intéressés peuvent lire les classes et méthodes prises en charge dans Web Workers. passer ElementRef nous permet d'encapsuler des éléments natifs dans la couche de vue sous différentes plateformes (dans un environnement de navigateur, les éléments natifs font généralement référence au DOM element), et enfin avec l'aide de la puissante fonctionnalité Dependency Injection fournie par Angular, nous pouvons facilement accéder aux éléments natifs.
export class ElementRef { public nativeElement: any; constructor(nativeElement: any) { this.nativeElement = nativeElement; } }
Commençons par présenter les exigences générales. Nous voulons obtenir l'élément p dans la page et changer la couleur d'arrière-plan de l'élément p une fois le rendu de la page réussi. Ensuite, nous mettrons en œuvre cette exigence étape par étape.
Nous devons d’abord obtenir l’élément p Dans la section « Rôle d’ElementRef » de l’article, nous avons mentionné que nous pouvons utiliser Angular. Fournit de puissantes fonctionnalités d’injection de dépendances pour obtenir des éléments natifs encapsulés. Dans le navigateur, l'élément natif est l'élément DOM. Il suffit de l'obtenir en premier. my-app, puis utilisez l'API querySelector pour obtenir l'élément p dans la page. Le code spécifique est le suivant :
import { Component, ElementRef } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <p>Hello {{ name }}</p> `, }) export class AppComponent { name: string = 'Semlinker'; constructor(private elementRef: ElementRef) { let pEle = this.elementRef.nativeElement.querySelector('p'); console.dir(pEle); } }
Lors de l'exécution du code ci-dessus, aucune exception ne se produit dans la console, mais le résultat de sortie est null . Que se passe-t-il? Sans lancer une exception, nous pouvons en déduire Cet objet.elementRef.nativeElement existe, mais ses éléments enfants sont introuvables. Cela devrait être le cas lorsque le constructeur est appelé, my-app. Les éléments enfants sous l'élément n'ont pas encore été créés. Alors comment résoudre ce problème ? En pensant... , n'y a-t-il pas setTimeout ? Nous le rénovons un peu :
constructor(private elementRef: ElementRef) { setTimeout(() => { // 此处需要使用箭头函数哈,你懂的... let pEle = this.elementRef.nativeElement.querySelector('p'); console.dir(pEle); }, 0); }
Problème résolu, mais pas très élégant ? Existe-t-il une meilleure solution ? La réponse est oui. Angular ne fournit pas de hooks cycle de vie des composants. Nous pouvons choisir un moment approprié et obtenir l'élément p que nous voulons.
import { Component, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <p>Hello {{ name }}</p> `, }) export class AppComponent { name: string = 'Semlinker'; // 在构造函数中 this.elementRef = elementRef 是可选的,编译时会自动赋值 // function AppComponent(elementRef) { this.elementRef = elementRef; } constructor(private elementRef: ElementRef) { } ngAfterViewInit() { // 模板中的元素已创建完成 console.dir(this.elementRef.nativeElement.querySelector('p')); // let greetp: HTMLElement = this.elementRef.nativeElement.querySelector('p'); // greetp.style.backgroundColor = 'red'; } }
En exécutant le code ci-dessus, nous voyons l'élément p attendu. On choisit directement ngAfterViewInit Ne me demandez pas pourquoi ce crochet est parce que c’est le plus agréable à l’œil. Cependant, nous aurons également un article spécial plus tard pour analyser en détail le cycle de vie des composants Angular. Obtenu avec succès p élément, le reste est simple. Définissez la couleur d’arrière-plan de l’élément directement via l’objet de style.
Bien que la fonction ait été implémentée, y a-t-il encore place à l’optimisation ?
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <p #greet>Hello {{ name }}</p> `, }) export class AppComponent { name: string = 'Semlinker'; @ViewChild('greet') greetp: ElementRef; ngAfterViewInit() { this.greetp.nativeElement.style.backgroundColor = 'red'; } }
Cela ne vous fait-il pas du bien instantanément ? Mais attendez une minute. Y a-t-il de la place pour une optimisation supplémentaire dans le code ci-dessus ? Nous voyons ce paramètre p L'arrière-plan de l'élément est l'environnement d'exécution de l'application par défaut dans le navigateur. Comme mentionné précédemment, nous devons minimiser la forte relation de couplage entre la couche application et la couche de rendu, afin que notre application puisse s'exécuter de manière flexible dans différents environnements. Enfin, jetons un œil au code optimisé final :
import { Component, ElementRef, ViewChild, AfterViewInit, Renderer } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <p #greet>Hello {{ name }}</p> `, }) export class AppComponent { name: string = 'Semlinker'; @ViewChild('greet') greetp: ElementRef; constructor(private elementRef: ElementRef, private renderer: Renderer) { } ngAfterViewInit() { // this.greetp.nativeElement.style.backgroundColor = 'red'; this.renderer.setElementStyle(this.greetp.nativeElement, 'backgroundColor', 'red'); } }
export abstract class Renderer { // 创建元素 abstract createElement(parentElement: any, name: string, debugInfo?: RenderDebugInfo): any; // 创建文本元素 abstract createText(parentElement: any, value: string, debugInfo?: RenderDebugInfo): any; // 设置文本 abstract setText(renderNode: any, text: string): void; // 设置元素Property abstract setElementProperty(renderElement: any, propertyName: string, propertyValue: any): void; // 设置元素Attribute abstract setElementAttribute(renderElement: any, attributeName: string, attributeValue: string): void; // 设置元素的Class abstract setElementClass(renderElement: any, className: string, isAdd: boolean): void; // 设置元素的样式 abstract setElementStyle(renderElement: any, styleName: string, styleValue: string): void; }
A noter que dans la version Angular 4.x+, nous utilisons Renderer2 au lieu de Renderer (Angular V2).
export abstract class Renderer2 { abstract createElement(name: string, namespace?: string|null): any; abstract createComment(value: string): any; abstract createText(value: string): any; abstract setAttribute(el: any, name: string, value: string, namespace?: string|null): void; abstract removeAttribute(el: any, name: string, namespace?: string|null): void; abstract addClass(el: any, name: string): void; abstract removeClass(el: any, name: string): void; abstract setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void; abstract removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void; abstract setProperty(el: any, name: string, value: any): void; abstract setValue(node: any, value: string): void; abstract listen( target: 'window'|'document'|'body'|any, eventName: string, callback: (event: any) => boolean | void): () => void; }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!