Heim > Web-Frontend > js-Tutorial > Hauptteil

Angular-Entwicklungspraxis (7): Plattformübergreifender Betrieb von DOM und Renderer2

不言
Freigeben: 2018-04-02 15:11:41
Original
4376 Leute haben es durchsucht

Am Ende des Artikels „Angular-Entwicklungspraxis (6): Serverseitiges Rendering“ haben wir auch einige Dinge erwähnt, die bei 服务端渲染 beachtet werden müssen, einschließlich der Nichtverwendung von window, document, navigator und andere browserspezifische Typen sowie direkte Manipulation von DOM-Elementen.

Das bringt uns zu einem der Hauptmerkmale von Angular: plattformübergreifend. Mit dem richtigen Ansatz können mit Angular erstellte Anwendungen auf mehreren verschiedenen Plattformen wiederverwendet werden – Web, mobiles Web, mobile Apps, native Apps und native Desktop-Apps.

Um plattformübergreifend zu unterstützen, kapselt Angular die Unterschiede verschiedener Plattformen durch Abstraktionsschichten. Beispielsweise sind die abstrakte Klasse Renderer2, die abstrakte Klasse RootRenderer usw. definiert. Darüber hinaus sind folgende Referenztypen definiert: ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef usw. Erhalten Sie DOM-Elemente über 模板变量, @ViewChild und andere Methoden.

Zur Demonstration definieren Sie zunächst eine Komponente DemoComponent:

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

@Component({
    template: `
        <p id="demop" #demop>this is p!</p>
        p的id:{{demop.id}} <!-- p的id:demop -->
    `
})
export class DemoComponent implements AfterViewInit {
    @ViewChild(&#39;demop&#39;) demop: ElementRef; // @ViewChild通过模板变量名获取

    constructor(private renderer: Renderer2) {
    }

    ngAfterViewInit() {
        console.log(&#39;p的id:&#39; + this.demop.nativeElement.id); // p的id:demop
        this.renderer.setStyle(this.demop.nativeElement, &#39;background-color&#39;, &#39;red&#39;); // 通过Renderer2设置p的css样式background-color
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Rufen Sie das p in der Komponente ab

In Angular-Anwendungen sollten Sie das DOM nicht direkt über die native Komponente abrufen API- oder jQuery-Element:

let element1 = document.getElementById("demop"); // jQuery获取: $(&#39;#demop&#39;)
Nach dem Login kopieren

Stattdessen sollten Sie das DOM-Element über die von Angular bereitgestellte Methode abrufen:

Vorlagenvariable

<p id="demop" #demop>this is p!</p>
p的id:{{demop.id}} <!-- p的id:demop -->
Nach dem Login kopieren
Nach dem Login kopieren

In der Komponentenvorlage , wir sind auf p Die Vorlagenvariable von #demop ist definiert, dann ist demop gleich dem DOM-Objekt von p, sodass wir die ID von p direkt über demop.id erhalten können.

@ViewChild

@ViewChild(&#39;demop&#39;) demop: ElementRef; // @ViewChild通过模板变量名获取

ngAfterViewInit() {
    console.log(&#39;p的id:&#39; + this.demop.nativeElement.id); // p的id:demop
}
Nach dem Login kopieren

In der Komponentenklasse erhalten wir das ElementRef-Objekt, das das DOM-Objekt mit p umschließt, durch @ViewChild. Das ElementRef ist wie folgt definiert:

class ElementRef<T> {
  constructor(nativeElement: T)
  nativeElement: T
}
Nach dem Login kopieren

So können wir das DOM-Objekt von p über this.demop.nativeElement in ngAfterViewInit abrufen und dann die ID des Elements abrufen.

p in der Betriebskomponente

hat das DOM-Objekt von p über mehrere der oben genannten Methoden erhalten. Was wollen wir also damit machen (Stile, Attribute festlegen, Unterelemente einfügen usw.)? .) ? Via Raw-API oder jQuery ist definitiv nicht erlaubt.

Auf diese Weise stellen wir die abstrakte Angular-Klasse vor Renderer2 zum Festlegen von Stilen, Attributen, zum Einfügen von Unterelementen und anderen Operationen an Elementen.

Renderer2 ist wie folgt definiert:

class Renderer2 {
    get data: {...}
    destroyNode: ((node: any) => void) | null
    destroy(): void
    createElement(name: string, namespace?: string | null): any // 创建元素
    createComment(value: string): any // 创建注释元素
    createText(value: string): any // 创建文本元素
    appendChild(parent: any, newChild: any): void // 添加子元素(在最后)
    insertBefore(parent: any, newChild: any, refChild: any): void // 添加子元素(在最前)
    removeChild(parent: any, oldChild: any): void // 移除子元素
    selectRootElement(selectorOrNode: string | any): any // 获取根元素
    parentNode(node: any): any // 获取父元素
    nextSibling(node: any): any // 获取下一个兄弟元素
    setAttribute(el: any, name: string, value: string, namespace?: string | null): void // 设置属性
    removeAttribute(el: any, name: string, namespace?: string | null): void // 移除属性
    addClass(el: any, name: string): void // 添加样式类
    removeClass(el: any, name: string): void // 移除样式类
    setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void // 设置样式
    removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void // 移除样式
    setProperty(el: any, name: string, value: any): void // 设置DOM对象属性,不同于元素属性
    setValue(node: any, value: string): void // 设置元素值
    listen(target: &#39;window&#39; | &#39;document&#39; | &#39;body&#39; | any, eventName: string, callback: (event: any) => boolean | void): () => void // 注册事件
}
Nach dem Login kopieren
Nach dem Login kopieren

Wenn wir also die Hintergrundfarbe von p ändern möchten, können wir Folgendes tun:

ngAfterViewInit() {
    this.renderer.setStyle(this.demop.nativeElement, &#39;background-color&#39;, &#39;red&#39;); // 通过Renderer2设置p的css样式background-color
}
Nach dem Login kopieren
Nach dem Login kopieren

                                     


Am Ende des Artikels „Angular Development Practice (6): Serverseitiges Rendering“ haben wir auch mehrere Ereignisse erwähnt, die in <🎜 berücksichtigt werden müssen > Dazu gehört, keine browserspezifischen Typen wie 服务端渲染, window, document zu verwenden und DOM-Elemente direkt zu manipulieren. navigator

Das bringt uns zu einem der Hauptmerkmale von Angular: plattformübergreifend. Mit dem richtigen Ansatz können mit Angular erstellte Anwendungen auf mehreren verschiedenen Plattformen wiederverwendet werden – Web, mobiles Web, mobile Apps, native Apps und native Desktop-Apps.

Um plattformübergreifend zu unterstützen, kapselt Angular die Unterschiede verschiedener Plattformen durch Abstraktionsschichten. Beispielsweise sind die abstrakte Klasse Renderer2, die abstrakte Klasse RootRenderer usw. definiert. Darüber hinaus sind folgende Referenztypen definiert: ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef usw. Erhalten Sie DOM-Elemente über

, 模板变量 und andere Methoden. @ViewChild

Zur Demonstration definieren Sie zunächst eine Komponente DemoComponent:

import { AfterViewInit, Component, ElementRef, Renderer2, ViewChild } from &#39;@angular/core&#39;;

@Component({
    template: `
        <p id="demop" #demop>this is p!</p>
        p的id:{{demop.id}} <!-- p的id:demop -->
    `
})
export class DemoComponent implements AfterViewInit {
    @ViewChild(&#39;demop&#39;) demop: ElementRef; // @ViewChild通过模板变量名获取

    constructor(private renderer: Renderer2) {
    }

    ngAfterViewInit() {
        console.log(&#39;p的id:&#39; + this.demop.nativeElement.id); // p的id:demop
        this.renderer.setStyle(this.demop.nativeElement, &#39;background-color&#39;, &#39;red&#39;); // 通过Renderer2设置p的css样式background-color
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Rufen Sie das p in der Komponente ab

In Angular-Anwendungen sollten Sie das DOM nicht direkt über die native Komponente abrufen API- oder jQuery-Element:

let element1 = document.getElementById("demop"); // jQuery获取: $(&#39;#demop&#39;)
Nach dem Login kopieren
Stattdessen sollten Sie das DOM-Element über die von Angular bereitgestellte Methode abrufen:

Vorlagenvariable

<p id="demop" #demop>this is p!</p>
p的id:{{demop.id}} <!-- p的id:demop -->
Nach dem Login kopieren
Nach dem Login kopieren
In der Komponentenvorlage , wir sind auf p Die Vorlagenvariable von #demop ist definiert, dann ist demop gleich dem DOM-Objekt von p, sodass wir die ID von p direkt über

erhalten können. demop.id

@ViewChild

@ViewChild(&#39;demop&#39;) demop: ElementRef; // @ViewChild通过模板变量名获取

ngAfterViewInit() {
    console.log(&#39;p的id:&#39; + this.demop.nativeElement.id); // p的id:demop
}
Nach dem Login kopieren
In der Komponentenklasse erhalten wir das ElementRef-Objekt, das das DOM-Objekt mit p umschließt, durch @ViewChild. Das ElementRef ist wie folgt definiert:

class ElementRef<T> {
  constructor(nativeElement: T)
  nativeElement: T
}
Nach dem Login kopieren
So können wir das DOM-Objekt von p über this.demop.nativeElement in ngAfterViewInit abrufen und dann die ID des Elements abrufen.

p in der Betriebskomponente

hat das DOM-Objekt von p über mehrere der oben genannten Methoden erhalten. Wie arbeiten wir also damit (Stile, Attribute festlegen, Unterelemente einfügen usw.)? ? Via Raw-API oder jQuery ist definitiv nicht erlaubt.

Auf diese Weise stellen wir die abstrakte Angular-Klasse vor

zum Festlegen von Stilen, Attributen, zum Einfügen von Unterelementen und anderen Operationen an Elementen. Renderer2

Renderer2 ist wie folgt definiert:

class Renderer2 {
    get data: {...}
    destroyNode: ((node: any) => void) | null
    destroy(): void
    createElement(name: string, namespace?: string | null): any // 创建元素
    createComment(value: string): any // 创建注释元素
    createText(value: string): any // 创建文本元素
    appendChild(parent: any, newChild: any): void // 添加子元素(在最后)
    insertBefore(parent: any, newChild: any, refChild: any): void // 添加子元素(在最前)
    removeChild(parent: any, oldChild: any): void // 移除子元素
    selectRootElement(selectorOrNode: string | any): any // 获取根元素
    parentNode(node: any): any // 获取父元素
    nextSibling(node: any): any // 获取下一个兄弟元素
    setAttribute(el: any, name: string, value: string, namespace?: string | null): void // 设置属性
    removeAttribute(el: any, name: string, namespace?: string | null): void // 移除属性
    addClass(el: any, name: string): void // 添加样式类
    removeClass(el: any, name: string): void // 移除样式类
    setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void // 设置样式
    removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void // 移除样式
    setProperty(el: any, name: string, value: any): void // 设置DOM对象属性,不同于元素属性
    setValue(node: any, value: string): void // 设置元素值
    listen(target: &#39;window&#39; | &#39;document&#39; | &#39;body&#39; | any, eventName: string, callback: (event: any) => boolean | void): () => void // 注册事件
}
Nach dem Login kopieren
Nach dem Login kopieren
Wenn wir also die Hintergrundfarbe von p ändern möchten, können wir Folgendes tun:

ngAfterViewInit() {
    this.renderer.setStyle(this.demop.nativeElement, &#39;background-color&#39;, &#39;red&#39;); // 通过Renderer2设置p的css样式background-color
}
Nach dem Login kopieren
Nach dem Login kopieren


Verwandte Empfehlungen:

Angular Development Practice (5): Eingehende Analyse der Änderungsüberwachung

Angular-Entwicklungspraxis (6): Serverseitiges Rendering

Angular-Entwicklungspraxis (1): Umgebungsvorbereitung und Framework-Konstruktion

Das obige ist der detaillierte Inhalt vonAngular-Entwicklungspraxis (7): Plattformübergreifender Betrieb von DOM und Renderer2. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage