Dieses Mal zeige ich Ihnen, wie Sie ElementRef in Angular4 verwenden. Was sind die Vorsichtsmaßnahmen für die Verwendung von ElementRef in Angular4? . .
Angulars Slogan lautet: „Ein Framework, mehrere Plattformen. Sowohl für Mobilgeräte als auch für Desktops geeignet (Ein Framework. Mobil & Desktop.)“, das heißt, Angular unterstützt die Entwicklung plattformübergreifender Anwendungen, wie zum Beispiel: Webanwendungen, mobile Webanwendungen, native mobile Anwendungen, native Desktopanwendungen usw.
Um plattformübergreifend zu unterstützen, kapselt Angular die Unterschiede verschiedener Plattformen durch eine Abstraktionsschicht und vereinheitlicht die API-Schnittstelle. Zum Beispiel die abstrakte Klasse Renderer und die abstrakte Klasse RootRenderer usw. Darüber hinaus sind folgende Referenztypen definiert: ElementRef, TemplateRef, ViewRef, ComponentRef und ViewContainerRef usw. Lassen Sie uns die ElementRef-Klasse analysieren:
Der direkte Betrieb des DOM in der Anwendungsschicht führt zu einer starken Kopplung zwischen der Anwendungsschicht und der Rendering-Schicht, was dazu führt, dass unsere Anwendung nicht in verschiedenen Umgebungen ausgeführt werden kann, z. B. als Web-Worker, da sie sich im Web befindet In der Worker-Umgebung kann das DOM nicht direkt manipuliert werden. Interessierte Leser können die in Web Workers unterstützten Klassen und Methoden lesen. passieren Mit ElementRef können wir native Elemente in der Ansichtsebene unter verschiedenen Plattformen kapseln (in einer Browserumgebung beziehen sich native Elemente normalerweise auf DOM). Element) und schließlich können wir mit Hilfe der leistungsstarken Funktion Dependency Injection von Angular problemlos auf native Elemente zugreifen.
export class ElementRef { public nativeElement: any; constructor(nativeElement: any) { this.nativeElement = nativeElement; } }
Lassen Sie uns zunächst die allgemeinen Anforderungen vorstellen. Wir möchten das p-Element auf der Seite abrufen und die Hintergrundfarbe des p-Elements ändern, nachdem die Seite erfolgreich gerendert wurde. Als nächstes werden wir diese Anforderung Schritt für Schritt umsetzen.
Zuerst müssen wir das p-Element erhalten. Im Abschnitt „Rolle von ElementRef“ des Artikels haben wir erwähnt, dass wir Angular verwenden können Bietet leistungsstarke Funktionen zur Abhängigkeitsinjektion, um gekapselte native Elemente zu erhalten. Im Browser ist das native Element das DOM-Element. Wir müssen es nur zuerst abrufen my-app-Element und verwenden Sie dann die querySelector-API, um das p-Element auf der Seite abzurufen. Der spezifische Code lautet wie folgt:
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); } }
Beim Ausführen des obigen Codes tritt in der Konsole keine Ausnahme auf, aber das Ausgabeergebnis ist null . Was ist los? Ohne eine Ausnahme auszulösen können wir daraus schließen Dieses.elementRef.nativeElement-Objekt existiert, aber seine untergeordneten Elemente können nicht gefunden werden. Es sollte vorhanden sein, wenn der -Konstruktor aufgerufen wird, my-app Die untergeordneten Elemente unter dem Element wurden noch nicht erstellt. Wie kann man dieses Problem lösen? Ich denke... , gibt es nicht setTimeout? Wir renovieren es ein wenig:
constructor(private elementRef: ElementRef) { setTimeout(() => { // 此处需要使用箭头函数哈,你懂的... let pEle = this.elementRef.nativeElement.querySelector('p'); console.dir(pEle); }, 0); }
Problem gelöst, aber nicht sehr elegant? Gibt es eine bessere Lösung? Die Antwort ist ja. Angular bietet keine Komponenten-Lebenszyklus--Hooks. Wir können einen geeigneten Zeitpunkt auswählen und das gewünschte p-Element erhalten.
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'; } }
Wenn wir den obigen Code ausführen, sehen wir das erwartete p-Element. Wir wählen direkt ngAfterViewInit Fragen Sie mich nicht, warum dieser Haken so ist, weil er für das Auge am angenehmsten ist. Allerdings werden wir später auch einen speziellen Artikel veröffentlichen, in dem wir den Lebenszyklus von Angular-Komponenten im Detail analysieren. Erfolgreich erhalten p Element, der Rest ist einfach. Legen Sie die Hintergrundfarbe des Elements direkt über das Stilobjekt fest.
Gibt es trotz der Implementierung der Funktion noch Optimierungspotenzial?
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'; } }
Fühlt es sich nicht sofort großartig an? Aber Moment mal: Gibt es im obigen Code noch Raum für weitere Optimierungen? Wir sehen diese Einstellung p Der Hintergrund des Elements ist die Standardumgebung für die Ausführung der Anwendung im Browser. Wie bereits erwähnt, müssen wir die starke Kopplungsbeziehung zwischen der Anwendungsschicht und der Rendering-Schicht minimieren, damit unsere Anwendung flexibel in verschiedenen Umgebungen ausgeführt werden kann. Werfen wir abschließend einen Blick auf den endgültigen optimierten Code:
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; }
Es ist zu beachten, dass wir in der Angular 4.x+-Version Renderer2 anstelle von Renderer (Angular V2) verwenden.
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中文网其它相关文章!
推荐阅读:
Das obige ist der detaillierte Inhalt vonSo verwenden Sie ElementRef in Angular4. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!