angular 4 viewchild nativeElement offsetWidth неожиданно меняется
У меня есть такой компонент:
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 по-другому, в зависимости от того, на какие другие страницы я перехожу?
Я использую встроенную угловую маршрутизацию в приложении, и у меня есть вложенные / дочерние маршруты. Я не знаю, полезна ли эта информация или нет.
Любая помощь здесь высоко ценится.
3 ответа
Я встречал подобную проблему, решенную установкой параметра чтения
Импортировать
import { ElementRef } from '@angular/core';
ViewChild
@ViewChild(MyComponent, { read: ElementRef }) myComponent : ElementRef
использование
onClick(){
console.log("directive width:", this.myComponent.nativeElement.offsetWidth)
}
проверить мета-свойства в документе
Первая проблема заключается в том, что вы не можете работать со своим HTML-представлением в ngOnInit. Вы должны реализовать интерфейс AfterViewInit и использовать метод:
ngAfterViewInit() {
// ...
}
В этом методе вы можете работать с html-компонентом, потому что компонент отображается и существует. Попробуй, надеюсь, это поможет.
Это обычная проблема в развитии клиентов. Обычно рекомендуется реализовать AfterViewInit и поместить код в тайм-аут. Однако я столкнулся с проблемами и с этим, в частности, с тем поведением, которое вы описываете. Я рекомендую использовать RxJ и реализовать что-то вроде следующего:
ngAfterViewInit(){ interval(300).pipe(take(2)).subscribe(() => { //your code here// }); }
Это дает довольно хорошую задержку, позволяющую отображать содержимое представления, а также делает второй проход, избегая использования неэффективного взлома AfterViewChecked и т. Д.