Dieser Artikel stellt hauptsächlich die Anwendung von Angular4 ElementRef vor. Jetzt teile ich ihn mit Ihnen und gebe ihn als Referenz.
Angulars Slogan lautet: „Ein Framework, mehrere Plattformen. Sowohl für Mobiltelefone als auch für Desktops geeignet (Ein Framework.Mobile & Desktop.)“, das heißt, Angular unterstützt die Entwicklung plattformübergreifender Anwendungen. wie zum Beispiel: Webanwendungen, mobile Webanwendungen, native mobile Anwendungen und native Desktopanwendungen usw.
Um plattformübergreifend zu unterstützen, kapselt Angular die Unterschiede verschiedener Plattformen durch eine Abstraktionsschicht und vereinheitlicht die API-Schnittstelle. Beispielsweise sind die abstrakte Klasse Renderer, die abstrakte Klasse RootRenderer usw. definiert. Darüber hinaus sind folgende Referenztypen definiert: ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef usw. Lassen Sie uns die ElementRef-Klasse analysieren:
Der direkte Betrieb des DOM in der Anwendungsschicht führt zu einer Lücke zwischen der Anwendungsschicht und dem Rendering Die starke Kopplung der Schicht verhindert, dass unsere Anwendungen in verschiedenen Umgebungen ausgeführt werden, z. B. in Web-Worker-Umgebungen, da das DOM in der Web-Worker-Umgebung nicht direkt manipuliert werden kann. Interessierte Leser können die in Web Workers unterstützten Klassen und Methoden lesen. Über ElementRef können wir native Elemente in der Ansichtsebene unter verschiedenen Plattformen kapseln (in einer Browserumgebung beziehen sich native Elemente normalerweise auf DOM-Elemente). Mithilfe der leistungsstarken Abhängigkeitsinjektionsfunktion von Angular können wir schließlich problemlos auf native Elemente zugreifen Elemente.
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 abrufen. Im Abschnitt „Rolle von ElementRef“ des Artikels haben wir erwähnt, dass wir die leistungsstarke Abhängigkeitsinjektionsfunktion von Angular verwenden können, um das gekapselte native Element zu erhalten Element. Im Browser ist das native Element das DOM-Element. Wir müssen nur zuerst das my-app-Element abrufen und dann die querySelector-API verwenden, 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 keine Ausnahme in der Konsole auf, aber das Ausgabeergebnis ist null . Was ist los? Es wird keine Ausnahme ausgelöst. Wir können daraus schließen, dass das Objekt this.elementRef.nativeElement existiert, seine untergeordneten Elemente jedoch nicht gefunden werden können. Dies sollte daran liegen, dass die untergeordneten Elemente unter dem my-app-Element noch nicht erstellt wurden, als der Konstruktor aufgerufen wurde. Wie kann man dieses Problem lösen? Ich denke... Gibt es da nicht setTimeout? Wir überarbeiten es ein wenig:
constructor(private elementRef: ElementRef) { setTimeout(() => { // 此处需要使用箭头函数哈,你懂的... let pEle = this.elementRef.nativeElement.querySelector('p'); console.dir(pEle); }, 0); }
Das Problem ist gelöst, aber es fühlt sich nicht an sehr elegant? Gibt es eine bessere Lösung? Die Antwort ist ja. Angular bietet keine Hooks für den Komponentenlebenszyklus. 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'; } }
Führen Sie den obigen Code aus und wir sehen das erwartete p-Element. Wir verwenden direkt den ngAfterViewInit-Hook. Fragen Sie mich nicht warum, denn er ist für das Auge am angenehmsten. Allerdings werden wir später auch einen speziellen Artikel veröffentlichen, in dem wir den Lebenszyklus von Angular-Komponenten im Detail analysieren. Nachdem Sie das p-Element erfolgreich erhalten haben, ist der Rest einfach. Legen Sie die Hintergrundfarbe des Elements direkt über das Stilobjekt fest.
Obwohl die Funktion implementiert wurde, gibt es noch Raum für Optimierungen?
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'; } }
Haben Sie das Gefühl, dass es Ihnen sofort besser geht? Gibt es Raum für eine weitere Optimierung des oben genannten Codes? Wir sehen, dass der Hintergrund des p-Elements festgelegt ist und wir die Standardumgebung für die Ausführung von Anwendungen im Browser sind. 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; }
Das oben Gesagte habe ich für Sie zusammengestellt. Ich hoffe, es wird Ihnen in Zukunft hilfreich sein.
Verwandte Artikel:
Probleme bei der Routing-Berechtigungsverwaltung mit Vue (ausführliches Tutorial)
Das obige ist der detaillierte Inhalt vonSo verwenden Sie die ElementRef-Anwendung in Angular4. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!