来自组件的Angular 2 getBoundingClientRect

lbr*_*him 8 javascript typescript angular

我有下面的组件,它基本上是一个popover:

import {Component, Input, ViewChild} from 'angular2/core'

declare var $: any;

@Component({
  selector: 'popover',
  template: `
  <div id="temp" [ngStyle]="{'position':'absolute', 'z-index':'10000', 'top': y + 'px', left: x + 'px'}"
       [hidden]="hidden" #temp>
    <ng-content></ng-content>
  </div>
  `
})
export class Popover {

  @ViewChild("temp") temp;

  private hidden: boolean = true;
  private y: number = 0;
  private x: number = 0;

  show(target, shiftx = 0, shifty = 0){
    let position = $(target).offset();
    this.x = position.left + shiftx;
    this.y = position.top + shifty;
    this.hidden = false;

    console.log("#temp", this.temp.nativeElement.getBoundingClientRect()); //all 0s
    console.log("temp id", document.getElementById('temp').getBoundingClientRect()); //all 0s
  }

  hide(){
    this.hidden = true;
  }
}
Run Code Online (Sandbox Code Playgroud)

show()方法内部我试图获得结果,getBoundingClientRect()但它返回0所有属性,但当我document.getElementById("temp").getBoundingClientRect()从Chrome的控制台输入时,我得到了适当的结果与属性中的实际值.为什么差异以及我可以做些什么来从我的组件中获取实际值?

lbr*_*him 5

由于某种原因,DOM 在显示后并未立即更新,因此,例如setTimeout10 就达到了目的。

  • setTimout 为 **0** 通常就足够了 (3认同)

小智 5

我会使用 ngAfterContentChecked()。它对我来说效果很好。

import { AfterContentChecked  } from '@angular/core';

export class ModelComponent implements AfterContentChecked  {
   ngAfterContentChecked() {
        //your code
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助。:)

  • 注意:`AfterContentChecked` 在 `ngAfterContentInit()` 和每个后续的 `ngDoCheck()` 之后调用。 (3认同)

小智 5

我没有使用可以多次触发的setTimeout或生命周期挂钩,而是通过将Renderer设置为监视窗口加载事件来解决它。

import { OnInit, Renderer2} from '@angular/core';

...

export class MyComponent implements  OnInit {

    constructor(private el: ElementRef, private render: Renderer2) {}

    ngOnInit() {
        this.render.listen('window', 'load', () => {
            const rect = this.el.nativeElement.getBoundingClientRect().top;
        })
    }

}
Run Code Online (Sandbox Code Playgroud)

也许这可以帮助某人的用例。