Angular - 避免 setTimeout() hack 以获得 div 宽度
Angular - avoiding setTimeout() hack to get div width
编写了一个 Angular 13 组件,每当 window 调整大小时,它都会在 div 中绘制一些东西。
问题是获取 div 的渲染宽度。如果我不使用延迟 170 毫秒的 setTimeout(),this.treemap.nativeElement.offsetWidth
为零。
由于每次 window 调整大小时树图都必须重新渲染,我还尝试从 ngAfterViewInit() 调度一个 window 调整大小事件,但它似乎也发生得太快(所以又一次, 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 中是否有更简单的方法来完成这项工作?
尝试调用 ngAfterViewChecked() 而不是 ngAfterViewInit()
您可以使用 ResizeObserver
来观察元素本身而不是 window。
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);
}
}
归功于此答案:
编写了一个 Angular 13 组件,每当 window 调整大小时,它都会在 div 中绘制一些东西。
问题是获取 div 的渲染宽度。如果我不使用延迟 170 毫秒的 setTimeout(),this.treemap.nativeElement.offsetWidth
为零。
由于每次 window 调整大小时树图都必须重新渲染,我还尝试从 ngAfterViewInit() 调度一个 window 调整大小事件,但它似乎也发生得太快(所以又一次, 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 是不是错误的生命周期事件挂钩(
在 Angular 13 中是否有更简单的方法来完成这项工作?
尝试调用 ngAfterViewChecked() 而不是 ngAfterViewInit()
您可以使用 ResizeObserver
来观察元素本身而不是 window。
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);
}
}
归功于此答案: