属性指令:在初始化时获取 ElementRef 宽度

Posted

技术标签:

【中文标题】属性指令:在初始化时获取 ElementRef 宽度【英文标题】:Attribute directive: Get an ElementRef width upon initialization 【发布时间】:2019-07-19 04:02:05 【问题描述】:

我无法在属性指令中获取 ElementRef 的宽度,因为它始终等于 0

我定义属性指令的元素是:

<ion-text myCustomDirective>Test Text</ion-text>

指令的实现是这样的:

import  Directive, ElementRef, OnInit  from '@angular/core';

@Directive(
  selector: '[myCustomDirective]'
)
export class MyCustomDirective implements OnInit 

  private element: any;

  constructor(
    private elementRef: ElementRef
  )  

  ngOnInit() 
    this.element = this.elementRef.nativeElement;
    console.log("Element width: " + this.element.offsetWidth) //The width here is always equal to 0
  

我尝试了不同的方法和属性,例如clientWidthgetComputedStyle(this.element)['width'],但我总是得到0

我认为问题在于该元素尚未在 onInit 钩子中呈现,我想不出从另一个钩子/方法中获取宽度的方法。

由于我的元素 ion-text 不会触发任何事件,因此我无法使用 HostListener 来获取元素初始化后的宽度。

你有什么建议吗?

谢谢!

编辑

即使尝试使用 ngAfterViewInit() 钩子也会返回 0 的宽度:

ngAfterViewInit(): void 
  console.log("Element width: " + this.elementRef.nativeElement.offsetWidth); // returns 0

【问题讨论】:

您可以尝试在 ngOnInit 中调用 setTimeout 以确保该值正在更改吗? 你试过 ngAfterViewInit()。它可能会解决您的问题 setTimeout 可以准确吗?我们如何确定给定的超时值足以使元素发生变化?此值可能会根据机器和正在执行代码的浏览器的性能而改变 关于 ngAfterViewInit(),我刚刚编辑了我的问题,提到即使使用它后我的宽度总是 0 我有 stackblitz,它工作正常这里是链接stackblitz.com/edit/… 【参考方案1】:

这个问题可能是由于在获取元素宽度时视图没有初始化。您在这里需要的是使用指令的另一个生命周期钩子。 ngAfterViewInit()

这里是解决方案

import  Directive, ElementRef, OnInit, AfterViewInit  from '@angular/core';

@Directive(
  selector: '[myCustomDirective]'
)
export class MyCustomDirective implements OnInit, AfterViewInit 

  private element: any;

  constructor(
    private elementRef: ElementRef
  )  

  ngOnInit() 

  ngAfterViewInit() 
    this.element = this.elementRef.nativeElement;
    console.log("Element width: " + this.element.offsetWidth) //The width here is always equal to 0
  

Here is solution on stackblitz

希望对您有所帮助。

【讨论】:

感谢您的建议。我编辑了我的问题以指出即使 ngAfterViewInit() 钩子返回的宽度为 0

以上是关于属性指令:在初始化时获取 ElementRef 宽度的主要内容,如果未能解决你的问题,请参考以下文章

angular2: ElementRef 获取 CSS 填充属性

Angular: 属性装饰器ViewChild终章

angular 2 中 Renderer 和 ElementRef 的区别

如何获取组件自己的 ElementRef 以检索此组件的 BoundingClientRect?

如何在 ElementRef (nativeEelement) 中设置 HTML 内容?

CocosCreator-获取游戏可见宽高,真实宽高