Home  >  Article  >  Web Front-end  >  How to use ElementRef in Angular4

How to use ElementRef in Angular4

php中世界最好的语言
php中世界最好的语言Original
2018-04-12 16:22:564803browse

This time I will bring you how to use ElementRef in Angular4, what are the precautions when using ElementRef in Angular4, the following is a practical case, let’s take a look .

Angular's slogan is - "One framework, multiple platforms. Suitable for both mobile and desktop (One framework.Mobile & desktop.)", that is, Angular supports the development of cross-platform applications, such as web applications, mobile web applications, native mobile applications and native desktop applications.

In order to support cross-platform, Angular encapsulates the differences of different platforms through an abstraction layer and unifies the API interface. For example, the abstract class Renderer and abstract class RootRenderer etc. In addition, the following reference types are defined: ElementRef, TemplateRef, ViewRef, ComponentRef and ViewContainerRef etc. Let’s analyze the ElementRef class:

The role of ElementRef

Directly operating the DOM in the application layer will cause strong coupling between the application layer and the rendering layer, causing our application to be unable to run in different environments, such as web workers, because in the web In the worker environment, the DOM cannot be directly manipulated. Interested readers can read the classes and methods supported in Web Workers. pass ElementRef allows us to encapsulate native elements in the view layer under different platforms (in a browser environment, native elements usually refer to DOM element), and finally with the help of the powerful Dependency Injection feature provided by Angular, we can easily access native elements.

ElementRef definition

export class ElementRef {
 public nativeElement: any;
 constructor(nativeElement: any) { this.nativeElement = nativeElement; }
}

Application of ElementRef

Let's first introduce the overall requirements. We want to get the p element in the page and change the background color of the p element after the page is successfully rendered. Next, we will implement this requirement step by step.

First we need to get the p element. In the "Role of ElementRef" section of the article, we have mentioned that we can use Angular Provides powerful dependency injection features to obtain encapsulated native elements. In the browser, the native element is the DOM element. We only need to get it first my-app element, and then use the querySelector API to get the p element in the page. The specific code is as follows:

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

When running the above code, no exception occurs in the console, but the output result is null . what's the situation ? No Exception is thrown, we can infer This.elementRef.nativeElement object exists, but its child elements cannot be found. It should be when calling the constructor, my-app The child elements under the element have not been created yet. So how to solve this problem? Thinking... Isn't there setTimeout? We are revamping it a little:

 constructor(private elementRef: ElementRef) {
 setTimeout(() => { // 此处需要使用箭头函数哈,你懂的...
   let pEle = this.elementRef.nativeElement.querySelector('p');
   console.dir(pEle);
  }, 0); }

Problem solved, but not very elegant? Is there a better solution? The answer is yes. Angular does not provide componentlifecycle hooks. We can choose a suitable time and then get the p element we want.

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

Running the above code, we see the expected p element. We directly use ngAfterViewInit Don’t ask me why this hook is because it is the most pleasing to the eye. However, we will also have a special article later to analyze the life cycle of Angular components in detail. Successfully obtained p element, the rest is easy. Set the background color of the element directly through the style object.

Although the function has been implemented, is there still room for optimization?

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

Doesn’t it feel great instantly? But wait a minute. Is there room for further optimization in the above code? We see that setting p The background of the element is the default application running environment in the browser. As mentioned before, we need to minimize the strong coupling relationship between the application layer and the rendering layer, so that our application can run flexibly in different environments. Finally, let’s take a look at the final optimized code:

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');
 }
}

1. What other commonly used methods are there in Renderer API?

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

It should be noted that in Angular 4.x version, we use Renderer2 instead of Renderer (Angular V2).

2.Renderer2 API 还有哪些常用的方法 ?

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

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Immutable.js怎样实现撤销重做效果

vue判断input输入内容有否有空格

FileReader实现上传图片之前本地先预览

The above is the detailed content of How to use ElementRef in Angular4. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn