current position:Home>Angular acquisition and operation DOM

Angular acquisition and operation DOM

2022-05-15 02:13:13Maple moving forward

ElementRef

Wrapper for a native element in the view .ElementRef  Behind the is a concrete element that can be rendered . In the browser , It's usually a DOM Elements .

class ElementRef<T> {
  constructor(nativeElement: T)
  nativeElement: T  // The original elements behind , If direct access to native elements is not supported , Then for  null( such as : stay  Web Worker  When running this application in the environment ).
}

When direct visit DOM when , Please take Ben API As a last resort . priority of use Angular Provided Template and data binding mechanism . Or you can see  Renderer2, It provides a safe to use API —— Even if the environment does not provide direct access to native elements .

If you rely on direct access DOM The way , It is possible to produce tight coupling between the application and the rendering layer . This will make it impossible to separate the two , You can't publish apps to Web Worker in .

import {
  Component,
  OnInit,
  ElementRef,
} from '@angular/core';
import { AboxItemComponent } from './abox-item/abox-item.component';

@Component({
  selector: 'app-abox',
  templateUrl: './abox.component.html',
  styleUrls: ['./abox.component.less'],
})
export class AboxComponent implements OnInit {
  private container;
  constructor(private el: ElementRef) {}

  ngOnInit(): void {}

  ngAfterViewInit(): void {
    this.container = this.el.nativeElement.querySelector('.container');
    console.log(this.el.nativeElement);
  }

}

  nativeElement What you get is all of the current component dom Elements

 

Use templates and data binding mechanisms , Use @viewChild

<p>abox works!</p>
<div class="wrapper">
  <div flyDirective #abc="flySub"></div>
  <div class="container" #containers>
    <div> Lonely smoke straight in the desert , Long river falling yen </div>
  </div>
  <ng-template #template></ng-template>
  <app-box-item #boxItem></app-box-item>
</div>

 

import {
  Component,
  OnInit,
  ViewChild,
  ElementRef,
  TemplateRef
} from '@angular/core';
import { AboxItemComponent } from './abox-item/abox-item.component';
import { FlyDirective } from './fly.directive';

@Component({
  selector: 'app-abox',
  templateUrl: './abox.component.html',
  styleUrls: ['./abox.component.less'],
})
export class AboxComponent implements OnInit {
  private container;
  @ViewChild('containers') containers: ElementRef;          // Get common elements 
  @ViewChild(AboxItemComponent) boxItem: AboxItemComponent; // Get components 
  @ViewChild('template') template: TemplateRef<any>;        // obtain ng-template

  // Can operate instructions , But here it is. FlyDirective The command needs to be set exportAs by flySub
  @ViewChild('abc') abc: FlyDirective;                      
  
  constructor() {}

  ngOnInit(): void {}

  ngAfterViewInit(): void {
    this.container = this.containers.nativeElement;
    console.log(this.container);
    console.log(this.abc.title);
  }
}

Renderer2

Using a custom renderer, you can bypass Angular The template mechanism of , And customization that cannot be expressed in declarative syntax UI change . such as , If you want to set a name that cannot be known statically Property or Attribute, have access to  setProperty()  or  setAttribute()  Method .

He provides a lot of operations dom Methods

abstract class Renderer2 {
  abstract data: {...}
  destroyNode: ((node: any) => void) | null
  abstract destroy(): void
  abstract createElement(name: string, namespace?: string): any
  abstract createComment(value: string): any
  abstract createText(value: string): any
  abstract appendChild(parent: any, newChild: any): void
  abstract insertBefore(parent: any, newChild: any, refChild: any): void
  abstract removeChild(parent: any, oldChild: any, isHostElement?: boolean): void
  abstract selectRootElement(selectorOrNode: any, preserveContent?: boolean): any
  abstract parentNode(node: any): any
  abstract nextSibling(node: any): any
  abstract setAttribute(el: any, name: string, value: string, namespace?: string): void
  abstract removeAttribute(el: any, name: string, namespace?: string): 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: any, eventName: string, callback: (event: any) => boolean | void): () => void
}
import {
  Component,
  OnInit,
  Renderer2,
  ViewChild,
} from '@angular/core';
import { AboxItemComponent } from './abox-item/abox-item.component';

@Component({
  selector: 'app-abox',
  templateUrl: './abox.component.html',
  styleUrls: ['./abox.component.less'],
})
export class AboxComponent implements OnInit {
  private container;
  activeIndex: number;
  @ViewChild('containers') containers: any;
  constructor(private renderer: Renderer2) {}

  ngOnInit(): void {}

  ngAfterViewInit(): void {
    this.container = this.containers.nativeElement;
    this.initCarouselWidth();
  }

  initCarouselWidth() {
    this.renderer.setStyle(this.container, 'width', '100px');
  }
}

Need to get and operate dom element , Try to use @viewChild and renderer2 Combine

copyright notice
author[Maple moving forward],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/132/202205120524480473.html

Random recommended