이 글은 주로 Angular4 ElementRef의 애플리케이션을 소개하고 있습니다.
Angular의 슬로건은 - "하나의 프레임워크, 다중 플랫폼. 휴대폰과 데스크톱 모두에 적합합니다(One Framework.Mobile & Desktop.)"입니다. 즉, Angular는 다음과 같은 크로스 플랫폼 애플리케이션 개발을 지원합니다. 모바일 웹 애플리케이션, 기본 모바일 애플리케이션 및 기본 데스크톱 애플리케이션 등
크로스 플랫폼을 지원하기 위해 Angular는 추상화 계층을 통해 다양한 플랫폼의 차이점을 캡슐화하고 API 인터페이스를 통합합니다. 예를 들어 추상 클래스 Renderer, 추상 클래스 RootRenderer 등이 정의됩니다. 또한 ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef 등의 참조 유형이 정의됩니다. 아래 ElementRef 클래스를 분석해 보겠습니다.
애플리케이션 계층에서 DOM을 직접 작동하면 애플리케이션 계층과 렌더링 계층 간의 강한 결합이 발생하여 애플리케이션이 다른 환경에서 실행될 수 없게 됩니다. , 예를 들어 웹 워커에서는 웹 워커 환경에서는 DOM을 직접 조작할 수 없기 때문입니다. 관심 있는 독자는 Web Workers에서 지원되는 클래스와 메서드를 읽어볼 수 있습니다. ElementRef를 통해 다양한 플랫폼의 뷰 레이어에 네이티브 요소를 캡슐화할 수 있습니다(브라우저 환경에서 네이티브 요소는 일반적으로 DOM 요소를 참조함). 마지막으로 Angular에서 제공하는 강력한 종속성 주입 기능을 사용하여 네이티브에 쉽게 액세스할 수 있습니다. 강요.
export class ElementRef { public nativeElement: any; constructor(nativeElement: any) { this.nativeElement = nativeElement; } }
먼저 전체 요구 사항을 소개하겠습니다. 페이지에서 p 요소를 가져오고 페이지가 성공한 후 p 요소의 배경색을 변경하겠습니다. 렌더링되었습니다. 다음으로 이 요구 사항을 단계별로 구현하겠습니다.
먼저 p 요소를 가져와야 합니다. 기사의 "ElementRef 역할" 섹션에서 Angular가 제공하는 강력한 종속성 주입 기능을 사용하여 캡슐화된 기본 요소를 가져올 수 있다고 언급했습니다. 브라우저에서 기본 요소는 DOM 요소입니다. 먼저 my-app 요소를 가져온 다음 querySelector API를 사용하여 페이지에서 p 요소를 가져옵니다. 구체적인 코드는 다음과 같습니다.
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); } }
위 코드를 실행하면 콘솔에서는 예외가 발생하지 않지만 출력 결과는 null 입니다. 무슨 일이야? 예외는 발생하지 않습니다. this.elementRef.nativeElement 객체가 존재한다고 추론할 수 있지만 해당 하위 요소를 찾을 수 없습니다. 이는 생성자가 호출될 때 my-app 요소 아래의 하위 요소가 아직 생성되지 않았기 때문입니다. 그렇다면 이 문제를 해결하는 방법은 무엇입니까? 생각해보니... setTimeout이 없나요? 조금 개조하는 중입니다.
constructor(private elementRef: ElementRef) { setTimeout(() => { // 此处需要使用箭头函数哈,你懂的... let pEle = this.elementRef.nativeElement.querySelector('p'); console.dir(pEle); }, 0); }
문제는 해결되었지만 별로 우아한 느낌이 들지 않나요? 더 나은 해결책이 있습니까? 대답은 '예'입니다. Angular는 구성 요소 수명 주기에 대한 후크를 제공하지 않으며 적절한 시간을 선택하고 원하는 p 요소를 얻을 수 있습니다.
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'; } }
위 코드를 실행하면 예상되는 p 요소가 표시됩니다. 우리는 ngAfterViewInit 후크를 직접 사용합니다. 이유는 묻지 마세요. 왜냐하면 이것이 눈에 가장 좋기 때문입니다. 하지만 나중에 Angular 구성 요소의 수명 주기를 자세히 분석하는 특별 기사도 준비하겠습니다. p 요소를 성공적으로 얻은 후에는 스타일 개체를 통해 요소의 배경색을 직접 설정하는 것이 쉽습니다.
기능은 구현됐지만 아직 최적화의 여지가 있나요?
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'; } }
키가 즉시 커졌다고 느끼시나요? 그런데 잠깐, 위 코드를 더 최적화할 여지가 있나요? p 요소의 배경이 설정되어 있고 브라우저의 기본 애플리케이션 실행 환경임을 알 수 있습니다. 앞서 언급했듯이 애플리케이션 계층과 렌더링 계층 간의 강력한 결합 관계를 최소화하여 애플리케이션이 다양한 환경에서 유연하게 실행될 수 있도록 해야 합니다. 마지막으로 최적화된 최종 코드를 살펴보겠습니다.
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; }
Angular 4.x+ 버전에서는 Renderer(Angular V2) 대신 Renderer2를 사용한다는 점에 유의해야 합니다.
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; }
위 내용은 제가 여러분을 위해 정리한 내용입니다. 앞으로 도움이 되길 바랍니다.
관련글:
Vue에서 컴포넌트 외부를 클릭하여 컴포넌트를 닫는 방법에 대해(상세 튜토리얼)
vue.js 태그 속성에 변수 매개변수를 삽입하는 방법에 대해(상세 튜토리얼)
Vue를 사용한 라우팅 권한 관리 문제(자세한 튜토리얼)
위 내용은 Angular4에서 ElementRef 애플리케이션을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!