Это потому, что в режиме разработки angular проверяет, что значения не изменились после обновления привязок. Изменение значений между ними может вызвать побочный эффект, например, неправильное отображение значения (см. Хорошее объяснение здесь )
В вашем примере:
- обнаружение изменений выполняется
- div еще не создан
- angular присваивает значение 1 свойству div
style.height
- браузер dr aws div
- angular снова запускает обнаружение изменений (только в режиме разработки)
- div существует, поэтому значение
style.height
больше не будет равно 1. Angular затем выдает ExpressionChangedAfterItHasBeenCheckedError
ошибку
Вам необходимо уведомить angular об изменении, используя ChangeDectorRef.detectChanges()
. Для этого вы можете вызвать метод компонента, поскольку вы не можете вызвать его напрямую из шаблона.
component.ts
lastWidth = 1;
@ViewChild('div', {static: true}) div: ElementRef;
constructor(private cdr:ChangeDetectorRef)
{
}
getWidth()
{
if(this.div)//Wzit until element is created
{
//Only call detectChanges if the previous value has changed
if(this.div.nativeElement.offsetWidth != this.lastWidth)
{
this.lastWidth = this.div.nativeElement.offsetWidth ;
this.cdr.detectChanges();
}
}
return this.lastWidth;
}
компонента. html
<div #div (window:resize)="0" [ngStyle]="{'height.px': getHeight() }">
Я создал демонстрацию стекаблика Демонстрация стекаблика , где вы можете динамически изменять размер div.
Примечание: вы также можете перенести изменение в setTimeout
вызов, который также решит проблему. Однако это снова запустит обнаружение изменений для всего приложения, а не только для интересующего вас компонента.