来自组件的Angular 2 getBoundingClientRect

时间:2016-06-17 12:05:53

标签: 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;
  }
}

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

4 个答案:

答案 0 :(得分:4)

我没有使用可以多次触发的setTimeout或生命周期钩子,而是通过设置渲染器来观察窗口加载事件来解决它。

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;
        })
    }

}

也许这有助于某人的使用。

答案 1 :(得分:3)

我会使用ngAfterContentChecked()。它对我来说非常好。

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

export class ModelComponent implements AfterContentChecked  {
   ngAfterContentChecked() {
        //your code
    }
}

我希望它有所帮助。 :)

答案 2 :(得分:2)

出于某种原因,DOM在显示之后没有立即更新,例如setTimeout 10诀窍。

答案 3 :(得分:0)

在这种情况下,ngAfterContentChecked有效。如上所述。

ngAfterContentChecked挂钩方法在生命周期中最后一个运行在ngOnDestroy之前。您可以阅读有关生命周期挂钩here的更多信息。

还请注意此处的操作,因为这可能会导致性能问题。

时间

在ngAfterViewInit()之后及其后的所有调用 ngAfterContentChecked()。