角度-@ViewChild上的“监听”更改

d4r*_*rty 6 angular

怎样onElChanged实现这样的功能,以便每次<div #plot id="plot-container"></div>更改属性时都执行该功能?

component.html

<div #plot id="plot-container"></div>
Run Code Online (Sandbox Code Playgroud)

component.ts

@ViewChild('plot') el: ElementRef;

onElChanged(){
  console.log(this.el.nativeElement.clientWidth);
}
Run Code Online (Sandbox Code Playgroud)

jmm*_*gle 12

虽然不是使用 @ViewChild 装饰器的解决方案,但您可以使用非常相似的@ViewChildren装饰器来订阅更改,尽管您观察到的特定主题是一个非类似列表的单一元素。

您可以使用first(or last)QueryList成员获取ElementRef值 - 忽略QueryList界面的大多数特定于列表的部分- 这是我在下面使用的快速而肮脏的方法。但是,可能建议将单个元素迭代处理为长度为 1 的列表,以坚持典型@ViewChildren范例并创建更通用的方法和服务。

@ViewChildren('plot', {read: ElementRef}) el: QueryList<ElementRef>;

/**
 * Listen within this component
 */
private listenForPlotChanges() {
    this.el.changes.subscribe(
        (next: QueryList<ElementRef>) => {
            console.log('listenForPlotChanges next:', next);

            const plot = next.first.nativeElement;
            console.log('listentForPlotChanges plot:', plot);
         }
    );
}
Run Code Online (Sandbox Code Playgroud)

或者来自存在于组件外部的侦听器的示例(特别考虑通过 说明对元素的更新Renderer2)...

import { ElementRef, Injectable, QueryList, Renderer2, RendererFactory2 } from '@angular/core';
import { ISubscription } from 'rxjs/Subscription';

/**
 * Listen and update with renderer as a service outside a component
 *
 * Usage:
 *  @ViewChildren('yourElement', {read: ElementRef}) el: QueryList<ElementRef>;
 *
 *  constructor(listener: ListenerService) {}
 *
 *  ngAfterViewInit() {
 *    this.listener.listenForPlotChanges(this.el);
 *  }
 */
@Injectable()
export class ListenerService {

private renderer: Renderer2;

constructor(rendererFactory: RendererFactory2) {
    this.renderer = rendererFactory.createRenderer(null, null);
}

listenForPlotChanges(elementQueryList: QueryList<ElementRef>): ISubscription {

    const resolveNext = (next) => {
            console.log('listenForPlotChanges next:', next);

            const plot = next.first.nativeElement;
            console.log('listentForPlotChanges plot:', plot);

            this.renderer.addClass(plot, 'twist');
    }

    return elementQueryList.changes.subscribe(
        (next: QueryList<ElementRef>) => {
            resolveNext(next);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在 Angular 版本中使用了我建议的方法,^5.2.1但尚未验证其他版本的 Angular,包括最新版本。


Nar*_*arm 8

您可以创建一个指令,使用MutationObserver来侦听 DOM 中特定元素的属性更改。

dom-change.directive.ts

import { Directive, ElementRef, EventEmitter, OnDestroy, Output } from '@angular/core';

@Directive({
  selector: '[domChange]'
})
export class DomChangeDirective implements OnDestroy {
  private changes: MutationObserver;

  @Output()
  public domChange = new EventEmitter();

  constructor(private elementRef: ElementRef) {
    const element = this.elementRef.nativeElement;

    this.changes = new MutationObserver((mutations: MutationRecord[]) => {
        mutations.forEach((mutation: MutationRecord) => this.domChange.emit(mutation));
      }
    );

    this.changes.observe(element, {
      attributes: true
    });
  }

  ngOnDestroy(): void {
    this.changes.disconnect();
  }
}
Run Code Online (Sandbox Code Playgroud)

组件.html

<div id="plot-container" (domChange)="onDomChange($event)"></div>
Run Code Online (Sandbox Code Playgroud)

组件.ts

onDomChange($event: Event): void {
    console.log($event);
  }
Run Code Online (Sandbox Code Playgroud)


Dav*_*sta 0

据我所知,没有办法监听元素的属性更改(对于这种情况)。尽管可能有其他一些库可以实现这一点。但这可能会有所帮助:

this.el.nativeElement.addEventListener(typeOfEvent);
Run Code Online (Sandbox Code Playgroud)