Heim  >  Artikel  >  Web-Frontend  >  Angular-Entwicklungspraxis (7): Plattformübergreifender Betrieb von DOM und Renderer2

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

不言
不言Original
2018-04-02 15:11:414384Durchsuche

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
    }
}

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获取: $('#demop')

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

Vorlagenvariable

a728b34f8c39ac4b8264402fa7a79be6this is p!94b3e26ee717c64999d7867364b1b4a3
p的id:{{demop.id}} 56a354faacebef689e1d2dd71ed7d1a6

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
}

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 ElementRef8742468051c85b06f0a0af9e3e506b5c {
  constructor(nativeElement: T)
  nativeElement: T
}

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 // 注册事件
}

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
}

                                     


Am Ende des Artikels „Angular Development Practice (6): Serverseitiges Rendering“ haben wir auch mehrere Ereignisse erwähnt, die in 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
    }
}
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;)
Stattdessen sollten Sie das DOM-Element über die von Angular bereitgestellte Methode abrufen:

Vorlagenvariable

a728b34f8c39ac4b8264402fa7a79be6this is p!94b3e26ee717c64999d7867364b1b4a3
p的id:{{demop.id}} 56a354faacebef689e1d2dd71ed7d1a6
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('demop') demop: ElementRef; // @ViewChild通过模板变量名获取

ngAfterViewInit() {
    console.log('p的id:' + this.demop.nativeElement.id); // p的id:demop
}
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
}
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 // 注册事件
}
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
}


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!

Stellungnahme:
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