Angular 角度-';听一听';关于@ViewChild更改

Angular 角度-';听一听';关于@ViewChild更改,angular,Angular,如何实现像onElChanged这样的函数,以便每次的属性更改时都执行这些函数 component.html <div id="plot-container" (domChange)="onDomChange($event)"></div> 据我所知,没有办法监听元素的属性更改(对于此场景)。尽管可能还有其他一些库可以实现这一点。不过,这可能会有所帮助: this.el.nativeElement.addEventListener(typeOfEvent); 您可以创

如何实现像
onElChanged
这样的函数,以便每次
的属性更改时都执行这些函数

component.html

<div id="plot-container" (domChange)="onDomChange($event)"></div>

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

this.el.nativeElement.addEventListener(typeOfEvent);

您可以创建一个指令,用于侦听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();
  }
}
onDomChange($event: Event): void {
    console.log($event);
  }
component.html

<div id="plot-container" (domChange)="onDomChange($event)"></div>

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

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


我在Angular版本
^5.2.1
中使用了我建议的方法,并且没有验证Angular的其他版本,包括最新版本。

是否有任何
typeOfEvent
在css属性更改时会触发?@d4rty您可以使用
new CustomEvent('cssChanged')实现自己的解决方案
并在应用任何css更改时发送customEvent。很好,但您有一个拼写错误查询列表->QueryListTypo已修复-谢谢。
onDomChange($event: Event): void {
    console.log($event);
  }
@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);
         }
    );
}
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);
        }
    }
}