Maison  >  Article  >  interface Web  >  Pratique de développement angulaire (7) : fonctionnement multiplateforme du DOM et du moteur de rendu Renderer2

Pratique de développement angulaire (7) : fonctionnement multiplateforme du DOM et du moteur de rendu Renderer2

不言
不言original
2018-04-02 15:11:414390parcourir

À la fin de l'article "Pratique de développement angulaire (6) : Rendu côté serveur" , nous avons également mentionné plusieurs choses à garder à l'esprit dans 服务端渲染, notamment ne pas utiliser window, document, navigator et autres types spécifiques au navigateur et manipulation directe des éléments DOM.

Cela nous amène à l’une des principales fonctionnalités d’Angular : le multiplateforme. Avec la bonne approche, les applications créées à l'aide d'Angular peuvent être réutilisées sur plusieurs plates-formes différentes : Web, Web mobile, applications mobiles, applications natives et applications de bureau natives.

Afin de prendre en charge plusieurs plates-formes, Angular encapsule les différences des différentes plates-formes à travers des couches d'abstraction. Par exemple, la classe abstraite Renderer2, la classe abstraite RootRenderer, etc. sont définies. De plus, les types de référence suivants sont définis : ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef, etc. Obtenez des éléments DOM via 模板变量, @ViewChild et d'autres méthodes.

Pour la démonstration, définissez d'abord un composant 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
    }
}

Récupérez le p dans le composant

Dans les applications angulaires, vous ne devez pas obtenir directement le DOM via le natif Élément API ou jQuery :

let element1 = document.getElementById("demop"); // jQuery获取: $('#demop')

Au lieu de cela, vous devez obtenir l'élément DOM via la méthode fournie par Angular :

Variable de modèle

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

Dans le modèle de composant , nous sommes sur p La variable modèle de #demop est définie, alors demop est égal à l'objet DOM de p, nous pouvons donc obtenir directement l'identifiant de p via demop.id.

@ViewChild

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

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

Dans la classe de composant, nous obtenons l'objet ElementRef qui encapsule l'objet DOM avec p via @ViewChild. L'ElementRef est défini comme suit :

class ElementRef8742468051c85b06f0a0af9e3e506b5c {
  constructor(nativeElement: T)
  nativeElement: T
}
Nous pouvons donc obtenir l'objet DOM de p via this.demop.nativeElement dans ngAfterViewInit, puis obtenir l'identifiant de l'élément.

p dans le composant opérationnel

a obtenu l'objet DOM de p grâce à plusieurs méthodes ci-dessus, alors que voulons-nous en faire (définir les styles, les attributs, insérer des sous-éléments, etc. .) ? Via l'API brute ou jQuery n'est certainement pas autorisé.

De cette façon, nous introduisons la classe abstraite Angular

pour définir des styles, des attributs, insérer des sous-éléments et d'autres opérations sur les éléments. Renderer2

Renderer2 est défini comme suit :

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 // 注册事件
}
Par conséquent, si nous voulons changer la couleur de fond de p, nous pouvons faire ceci :

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


À la fin de l'article "Pratique de développement angulaire (6) : Rendu côté serveur", nous avons également mentionné plusieurs événements à garder à l'esprit dans

, Il s'agit notamment de ne pas utiliser de types spécifiques au navigateur tels que 服务端渲染, window, document et de manipuler directement les éléments DOM. navigator

Cela nous amène à l’une des principales fonctionnalités d’Angular : le multiplateforme. Avec la bonne approche, les applications créées à l'aide d'Angular peuvent être réutilisées sur plusieurs plates-formes différentes : Web, Web mobile, applications mobiles, applications natives et applications de bureau natives.

Afin de prendre en charge plusieurs plates-formes, Angular encapsule les différences des différentes plates-formes à travers des couches d'abstraction. Par exemple, la classe abstraite Renderer2, la classe abstraite RootRenderer, etc. sont définies. De plus, les types de référence suivants sont définis : ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef, etc. Obtenez des éléments DOM via

, 模板变量 et d'autres méthodes. @ViewChild

Pour la démonstration, définissez d'abord un composant 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
    }
}
Récupérez le p dans le composant

Dans les applications angulaires, vous ne devez pas obtenir directement le DOM via le natif Élément API ou jQuery :

let element1 = document.getElementById("demop"); // jQuery获取: $(&#39;#demop&#39;)
Au lieu de cela, vous devez obtenir l'élément DOM via la méthode fournie par Angular :

Variable de modèle

a728b34f8c39ac4b8264402fa7a79be6this is p!94b3e26ee717c64999d7867364b1b4a3
p的id:{{demop.id}} 56a354faacebef689e1d2dd71ed7d1a6
Dans le modèle de composant , nous sommes sur p La variable modèle de #demop est définie, alors demop est égal à l'objet DOM de p, nous pouvons donc obtenir directement l'identifiant de p via

. demop.id

@ViewChild

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

ngAfterViewInit() {
    console.log('p的id:' + this.demop.nativeElement.id); // p的id:demop
}
Dans la classe de composant, nous obtenons l'objet ElementRef qui encapsule l'objet DOM avec p via @ViewChild. L'ElementRef est défini comme suit :

Nous pouvons donc obtenir l'objet DOM de p via this.demop.nativeElement dans ngAfterViewInit, puis obtenir l'identifiant de l'élément.
class ElementRef<T> {
  constructor(nativeElement: T)
  nativeElement: T
}

p dans le composant opérationnel

a obtenu l'objet DOM de p grâce à plusieurs méthodes ci-dessus, alors comment pouvons-nous opérer dessus (définir les styles, les attributs, insérer des sous-éléments, etc.) ? Via l'API brute ou jQuery n'est certainement pas autorisé.

De cette façon, nous introduisons la classe abstraite Angular

pour définir des styles, des attributs, insérer des sous-éléments et d'autres opérations sur les éléments.

Renderer2Renderer2 est défini comme suit :

Par conséquent, si nous voulons changer la couleur de fond de p, nous pouvons faire ceci :
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 // 注册事件
}

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


Recommandations associées :

Pratique de développement angulaire (5) : analyse approfondie de la surveillance des changements

Pratique de développement angulaire (6) : rendu côté serveur

Pratique de développement angulaire (1) : préparation de l'environnement et construction du cadre

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn