如何实现像onElChanged
这样的函数,以便每次<div #plot id="plot-container"></div>
的属性发生变化时都会执行此函数?
component.html
<div #plot id="plot-container"></div>
component.ts
@ViewChild('plot') el: ElementRef;
onElChanged(){
console.log(this.el.nativeElement.clientWidth);
}
答案 0 :(得分:1)
我知道,没有办法监听元素的属性更改(对于这种情况)。虽然可能有一些其他库可以实现这一目标。这可能会有所帮助:
this.el.nativeElement.addEventListener(typeOfEvent);
答案 1 :(得分:1)
您可以创建一个指令,使用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();
}
}
<强> component.html 强>
<div id="plot-container" (domChange)="onDomChange($event)"></div>
<强> component.ts 强>
onDomChange($event: Event): void {
console.log($event);
}
答案 2 :(得分:0)
虽然不是使用@ViewChild装饰器的解决方案,但尽管您观察到的特定主题是非列表式的单数元素,但您仍可以使用非常相似的@ViewChildren
装饰器来订阅更改
您可以使用first
(或last
)QueryList
成员来获取ElementRef
值-忽略{{1}的大多数列表特定部分}介面-这是我在下面使用的快速而肮脏的方法。 但是,建议您迭代处理一个长度为1的单数元素,以遵循典型的QueryList
范式并创建更通用的方法和服务。
@ViewChildren
或来自组件外部存在的侦听器的示例(出于特殊考虑,通过@ViewChildren('plot', {read: ElementRef}) el: QueryList<ElementRef>;
/**
* Listen within this component
*/
private listenForPlotChanges() {
this.el.changes.subscribe(
(next: QuerList<ElementRef>) => {
console.log('listenForPlotChanges next:', next);
const plot = next.first.nativeElement;
console.log('listentForPlotChanges plot:', plot);
}
);
}
说明了对元素的更新)...
Renderer2
我在Angular版本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);
}
}
}
中使用了建议的方法,但尚未对其他Angular版本(包括最新版本)进行验证。