angular 4 viewchild nativeElement offsetWidth意外更改

时间:2017-10-09 00:41:05

标签: angular viewchild

我有一个像这样的组件:

import { Component, OnInit, OnChanges, ViewChild, ElementRef, Input, Output, ViewEncapsulation, EventEmitter, AfterViewInit } from '@angular/core';
import * as d3 from 'd3';

@Component({
  selector: 'coefficient-histogram',
  templateUrl: './coefficient-histogram.component.html',
  styleUrls: ['./coefficient-histogram.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class CoefficientHistogramComponent implements OnInit {

  @ViewChild('coefficienthistogram') private chartContainer:ElementRef;

  constructor() { }

  ngOnInit() {
    let element = this.chartContainer.nativeElement;
    console.log(element.offsetWidth);
  }
}

使用如此模板:

<div class="coefficenthistogram" #coefficienthistogram style="width: 100%; height: 100%"></div>

当我第一次浏览到包含组件的页面(或刷新页面)时,控制台将offsetWidth记录为504,这是正确的大小,因为包含此元素的封闭div是该大小。但是,当我导航到另一个页面然后返回到此页面时,它会报告不同的大小(308),这与它所在的容器不匹配。此外,如果我导航到另一个页面,然后返回到此页面,它会报告不同的大小(126)。

页面本身不会更改 - 此组件的容器不会更改大小。我已经在Chrome调试器中对此进行了验证 - 无论是加载新页面还是从其他页面导航到该页面,封闭div的宽度为504。

什么会导致offsetWidth以我导航到???

的其他页面的不同方式报告

我在应用程序中使用原生角度4路由,并且我有嵌套/子路由。我不知道这些信息是否有用。

这里的任何帮助都非常感谢。

3 个答案:

答案 0 :(得分:1)

  

我遇到了类似的问题,通过设置读取参数

解决了这个问题

导入

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

<强> ViewChild

@ViewChild(MyComponent, { read: ElementRef }) myComponent : ElementRef 

使用

onClick(){
    console.log("directive width:", this.myComponent.nativeElement.offsetWidth)
}

检查 doc

上的元属性

答案 1 :(得分:0)

第一个问题是您无法在ngOnInit中使用您的视图html。您必须实现AfterViewInit接口并使用方法:

  ngAfterViewInit() {
    // ...
  }

在此方法中,您可以使用html组件,因为组件已呈现并存在。尝试一下,我希望也许会有所帮助。

答案 2 :(得分:0)

这是客户端开发中的常见痛点。通常建议实现 AfterViewInit 并将您的代码置于超时状态。但是,我也遇到了这个问题,特别是您描述的行为类型。我建议利用 RxJs 并实现如下内容:

ngAfterViewInit(){ interval(300).pipe(take(2)).subscribe(() => { //your code here// }); }

这为让视图内容呈现提供了相当好的延迟,并且还进行了第二遍,避免了必须使用低效的 AfterViewChecked hack 等。