In "Angular 개발 실습(6): 서버 측 렌더링"이 글의 마지막 부분에서는 서버 측 렌더링
에서 기억해야 할 몇 가지 사항도 언급했습니다. window
, document
, navigator
와 같은 브라우저별 유형을 사용하고 DOM 요소를 직접 조작합니다. 服务端渲染
中需要牢记的几件事件,其中就包括不要使用window
、 document
、 navigator
等浏览器特有的类型以及直接操作DOM元素。
这样就引出了 Angular 主要特性之一:横跨所有平台。通过合适的方法,使用 Angular 构建的应用,可复用在多种不同平台的应用上 —— Web、移动 Web、移动应用、原生应用和桌面原生应用。
为了能够支持跨平台,Angular 通过抽象层封装了不同平台的差异。比如定义了抽象类 Renderer2 、抽象类 RootRenderer 等。此外还定义了以下引用类型:ElementRef、TemplateRef、ViewRef 、ComponentRef 和 ViewContainerRef 等。通过 模板变量
、@ViewChild
等方法获取DOM元素。
为了演示,先定义一个组件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('demop') demop: ElementRef; // @ViewChild通过模板变量名获取 constructor(private renderer: Renderer2) { } ngAfterViewInit() { console.log('p的id:' + this.demop.nativeElement.id); // p的id:demop this.renderer.setStyle(this.demop.nativeElement, 'background-color', 'red'); // 通过Renderer2设置p的css样式background-color } }
在Angular应用中不应该通过原生 API 或者 jQuery 来直接获取DOM元素:
let element1 = document.getElementById("demop"); // jQuery获取: $('#demop')
而是应该通过Angular提供的方法来获取DOM元素:
<p id="demop" #demop>this is p!</p> p的id:{{demop.id}} <!-- p的id:demop -->
在组件模板中,我们在 p 上定义了 #demop 的模板变量,那么 demop 就等于该 p 的 DOM 对象,因此我们可以通过 demop.id
直接获取 p 的 id。
@ViewChild('demop') demop: ElementRef; // @ViewChild通过模板变量名获取 ngAfterViewInit() { console.log('p的id:' + this.demop.nativeElement.id); // p的id:demop }
在组件类中,我们通过 @ViewChild 获取到包装有 p 的 DOM 对象的 ElementRef 对象,ElementRef 定义如下:
class ElementRef<T> { constructor(nativeElement: T) nativeElement: T }
因此我们可以在 ngAfterViewInit 中通过 this.demop.nativeElement 获取到该 p 的 DOM 对象,然后获取元素的id。
在上面通过几种方式获取到 p 的 DOM 对象,那么我们要如果对它进行操作呢(设置样式、属性、插入子元素等)?通过原始API 或者 jQuery 肯定是不允许的了。
这样我们就引出Angular抽象类 Renderer2
来对元素进行设置样式、属性、插入子元素等操作。
Renderer2 的定义如下:
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: 'window' | 'document' | 'body' | any, eventName: string, callback: (event: any) => boolean | void): () => void // 注册事件 }
因此,我们想改变 p 的背景色,就可以这样做:
ngAfterViewInit() { this.renderer.setStyle(this.demop.nativeElement, 'background-color', 'red'); // 通过Renderer2设置p的css样式background-color }
在《Angular开发实践(六):服务端渲染》这篇文章的最后,我们也提到了在服务端渲染
中需要牢记的几件事件,其中就包括不要使用window
、 document
、 navigator
等浏览器特有的类型以及直接操作DOM元素。
这样就引出了 Angular 主要特性之一:横跨所有平台。通过合适的方法,使用 Angular 构建的应用,可复用在多种不同平台的应用上 —— Web、移动 Web、移动应用、原生应用和桌面原生应用。
为了能够支持跨平台,Angular 通过抽象层封装了不同平台的差异。比如定义了抽象类 Renderer2 、抽象类 RootRenderer 等。此外还定义了以下引用类型:ElementRef、TemplateRef、ViewRef 、ComponentRef 和 ViewContainerRef 等。通过 模板变量
、@ViewChild
等方法获取DOM元素。
为了演示,先定义一个组件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('demop') demop: ElementRef; // @ViewChild通过模板变量名获取 constructor(private renderer: Renderer2) { } ngAfterViewInit() { console.log('p的id:' + this.demop.nativeElement.id); // p的id:demop this.renderer.setStyle(this.demop.nativeElement, 'background-color', 'red'); // 通过Renderer2设置p的css样式background-color } }
在Angular应用中不应该通过原生 API 或者 jQuery 来直接获取DOM元素:
let element1 = document.getElementById("demop"); // jQuery获取: $('#demop')
而是应该通过Angular提供的方法来获取DOM元素:
<p id="demop" #demop>this is p!</p> p的id:{{demop.id}} <!-- p的id:demop -->
在组件模板中,我们在 p 上定义了 #demop 的模板变量,那么 demop 就等于该 p 的 DOM 对象,因此我们可以通过 demop.id
直接获取 p 的 id。
@ViewChild('demop') demop: ElementRef; // @ViewChild通过模板变量名获取 ngAfterViewInit() { console.log('p的id:' + this.demop.nativeElement.id); // p的id:demop }
在组件类中,我们通过 @ViewChild 获取到包装有 p 的 DOM 对象的 ElementRef 对象,ElementRef 定义如下:
class ElementRef<T> { constructor(nativeElement: T) nativeElement: T }
因此我们可以在 ngAfterViewInit 中通过 this.demop.nativeElement 获取到该 p 的 DOM 对象,然后获取元素的id。
在上面通过几种方式获取到 p 的 DOM 对象,那么我们要如果对它进行操作呢(设置样式、属性、插入子元素等)?通过原始API 或者 jQuery 肯定是不允许的了。
这样我们就引出Angular抽象类 Renderer2
템플릿 변수
및 @ViewChild
와 같은 메서드를 통해 DOM 요소를 가져옵니다. 데모를 위해 먼저 구성 요소를 정의합니다. DemoComponent: 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: 'window' | 'document' | 'body' | any, eventName: string, callback: (event: any) => boolean | void): () => void // 注册事件 }
ngAfterViewInit() { this.renderer.setStyle(this.demop.nativeElement, 'background-color', 'red'); // 通过Renderer2设置p的css样式background-color }
대신 다음과 같이 해야 합니다. pass DOM 요소를 얻기 위해 Angular에서 제공하는 메소드:
컴포넌트 템플릿에서 p에 #demop라는 템플릿 변수를 정의한 다음, 데모는 p의 DOM 객체와 같습니다. demop.id
를 통해 p의 id를 직접 얻을 수 있습니다. @ViewChild
rrreee컴포넌트 클래스에서는 @ViewChild를 통해 DOM 객체를 p로 래핑하는 ElementRef 객체를 얻습니다.
Renderer2
를 소개합니다. 🎜🎜Renderer2는 다음과 같이 정의됩니다. 🎜rrreee🎜 따라서 p의 배경색을 변경하려면 다음과 같이 하면 됩니다. 🎜rrreee🎜
🎜🎜🎜🎜"Angular Development Practice (6): Server-side Rendering" 기사 마지막 부분에서 서버 측 렌더링
의 필요성에 대해서도 언급했습니다. > 명심해야 할 몇 가지 사항에는 window
, document
, navigator
와 같은 브라우저별 유형을 사용하지 않고 DOM 요소를 직접 조작하는 것이 포함됩니다. 🎜🎜이것은 Angular의 주요 기능 중 하나인 크로스 플랫폼을 소개합니다. 올바른 접근 방식을 사용하면 Angular를 사용하여 구축된 애플리케이션을 웹, 모바일 웹, 모바일 앱, 기본 앱, 데스크톱 기본 앱 등 다양한 플랫폼에서 재사용할 수 있습니다. 🎜🎜크로스 플랫폼을 지원하기 위해 Angular는 추상화 계층을 통해 다양한 플랫폼의 차이점을 캡슐화합니다. 예를 들어 추상 클래스 Renderer2, 추상 클래스 RootRenderer 등이 정의되어 있습니다. 또한 ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef 등의 참조 유형이 정의됩니다. 템플릿 변수
및 @ViewChild
와 같은 메서드를 통해 DOM 요소를 가져옵니다. 🎜🎜데모를 위해 먼저 구성 요소를 정의합니다. DemoComponent: 🎜rrreee
demop.id
를 통해 p의 id를 직접 얻을 수 있습니다. 🎜Renderer2
를 소개합니다. 🎜🎜Renderer2는 다음과 같이 정의됩니다. 🎜rrreee🎜 따라서 p의 배경색을 변경하려면 다음과 같이 하면 됩니다. 🎜rrreee🎜🎜🎜🎜관련 권장 사항: 🎜🎜🎜Angular 개발 실습(5): In- 변화 모니터링에 대한 심층 분석🎜🎜
Angular 개발 실습(1): 환경 준비 및 프레임워크 구축
위 내용은 Angular 개발 사례(7): DOM 및 렌더러 Renderer2의 크로스 플랫폼 작업의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!