Angular-避免setTimeout()破解以获取div宽度



编写一个Angular 13组件,每当窗口调整大小时,该组件都会在div中绘制一些东西。

问题是获取div的渲染宽度。如果我不使用延迟170ms的setTimeout((,则this.treemap.nativeElement.offsetWidth为零。

由于每次窗口调整大小时树图都必须重新渲染,我还尝试从ngAfterViewInit((中调度窗口调整大小事件,但它似乎发生得太快了(所以this.treemap.nativeElement.offsetWidth为零(。

释放模板的一部分。。。

<div #treemap class="treemap col-12"></div>

和缩写代码。。。

// Details omitted for brevity
export class TreemapComponent implements AfterViewInit {
@ViewChild('treemap') treemap!: ElementRef
@HostListener('window:resize', ['$event'])
private render() {
const width = this.treemap.nativeElement.offsetWidth
// code that successfully renders a treemap in the div as long as width != 0
}
callHack(): void {
setTimeout(() => this.render(), 170) // testing shows 170ms is lowest possible
}
ngAfterViewInit(): void {
this.callHack()
// window.dispatchEvent(new Event('resize')) // happens too fast (offsetWidth = 0)
}

AfterViewInit是错误的生命周期事件挂钩吗(这篇文章建议使用ngAfterViewInit(?

在Angular 13中,有没有一种不那么棘手的方法来实现这一点?

您可以使用ResizeObserver来观察元素本身,而不是窗口。

export class TreemapComponent implements AfterViewInit, OnDestroy {
@ViewChild('treemap') treemap!: ElementRef;
treemapObserver = new ResizeObserver(() => this.render());
private render() {
const width = this.treemap.nativeElement.offsetWidth;
// code that successfully renders a treemap in the div as long as width != 0
}
ngAfterViewInit(): void {
this.treemapObserver.observe(this.treemap.nativeElement);
}
ngOnDestroy() {
this.treemapObserver.unobserve(this.treemap.nativeElement);
}
}

这个答案值得称赞:https://stackoverflow.com/a/39312522/12914833

尝试调用ngAfterViewChecked((而不是ngAfterView Init((

相关内容

  • 没有找到相关文章

最新更新