Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度8使元素为正方形抛出错误:表达式ChangedTerithasBeenCheckedError_Angular_Angular8 - Fatal编程技术网

Angular 角度8使元素为正方形抛出错误:表达式ChangedTerithasBeenCheckedError

Angular 角度8使元素为正方形抛出错误:表达式ChangedTerithasBeenCheckedError,angular,angular8,Angular,Angular8,我想动态地做一个div正方形。我找到了解决办法 它确实有效,但这个错误使我不安。谁能帮我摆脱那个错误 提前感谢它在开发模式下工作,但在生产构建中可能无法正常工作。试着看看这个,理解这个错误意味着什么 要消除此错误,可以在设置高度后手动强制再次运行 我创造了简单的 HTML: <div #div (window:resize)="0" [ngStyle]="{'height.px': dynamicDivHeight }"></div> ... export class

我想动态地做一个div正方形。我找到了解决办法

它确实有效,但这个错误使我不安。谁能帮我摆脱那个错误


提前感谢

它在开发模式下工作,但在生产构建中可能无法正常工作。试着看看这个,理解这个错误意味着什么

要消除此错误,可以在设置高度后手动强制再次运行

我创造了简单的

HTML:

<div #div (window:resize)="0" [ngStyle]="{'height.px': dynamicDivHeight }"></div>
...
export class Component implements AfterViewInit  {

    @ViewChild('div', { static: false } ) div: ElementRef<HTMLDivElement>; // element reference

    dynamicDivHeight: number = 1;

    constructor(private changeDetectorRef: ChangeDetectorRef) {
    }


    ngAfterViewInit() {    // if you are working with native html elements, you should be doing it in AfterViewInit hook
        this.dynamicDivHeight = this.div.nativeElement.offsetWidth;     // set the dynamic height
        this.changeDetectorRef.detectChanges();     // manually force change detection
    }
}

TS:

<div #div (window:resize)="0" [ngStyle]="{'height.px': dynamicDivHeight }"></div>
...
export class Component implements AfterViewInit  {

    @ViewChild('div', { static: false } ) div: ElementRef<HTMLDivElement>; // element reference

    dynamicDivHeight: number = 1;

    constructor(private changeDetectorRef: ChangeDetectorRef) {
    }


    ngAfterViewInit() {    // if you are working with native html elements, you should be doing it in AfterViewInit hook
        this.dynamicDivHeight = this.div.nativeElement.offsetWidth;     // set the dynamic height
        this.changeDetectorRef.detectChanges();     // manually force change detection
    }
}
。。。
导出类组件实现AfterViewInit{
@ViewChild('div',{static:false})div:ElementRef;//元素引用
dynamicDivHeight:数字=1;
构造函数(专用changeDetectorRef:changeDetectorRef){
}
ngAfterViewInit(){//如果您使用的是本机html元素,那么应该在AfterViewInit钩子中进行
this.dynamicDivHeight=this.div.nativeElement.offsetWidth;//设置动态高度
this.changeDetectorRef.detectChanges();//手动强制更改检测
}
}

这是因为在开发模式下,angular检查值在更新绑定后是否没有更改。在两个值之间进行更改可能会产生副作用,例如没有显示正确的值(请参阅良好的解释)

在您的示例中:

  • 更改检测运行
  • 尚未创建div
  • angular将值1指定给div的
    style.height
    属性
  • 浏览器将绘制div
  • 再次执行角度变化检测(仅在开发模式下)
  • div存在,因此
    style.height
    值不再是1。Angular然后抛出一个
    表达式ChangedTerithasBeenCheckedError
    错误
您需要使用
ChangeDectorRef.detectChanges()
将更改通知angular。为此,您可以调用组件的方法,因为您不能直接从模板调用它

组件。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;

  }
component.html

<div #div  (window:resize)="0" [ngStyle]="{'height.px': getHeight() }">

我创建了一个stackblitz,您可以动态调整div的大小


注意:您还可以在
setTimeout
调用中包装更改,这也可以解决问题。但是,这将再次为整个应用程序运行更改检测,而不仅仅是您感兴趣的组件

此问题仅在开发模式下发布。在AngularJS中引入它是为了避免摘要循环中的循环问题(AngularJS中的问题)

在绑定上成功运行更改检测循环后,Angular再次通过运行更改检测来检查绑定是否已更改。若任何值发生变化,Angular将在控制台中抛出此错误

请通过这个有趣的博客来了解

如上所述,这是因为Angular运行另一个循环来检查任何绑定的值是否已更改。因此,通过使用setTimeout异步运行,可以轻松跳过连续的更改

setTimeout(() => {
  this.lastWidth = this.div.nativeElement.offsetWidth;
});
您还可以按照上面的回答手动使用更改检测


请参阅此工作stackblitz:“

setTimeout
触发整个应用程序的更改检测,而
detectionChanges
仅对当前组件及其子组件执行此操作。实际上,您可以使用CSS技巧,根据简单的填充属性以任何比率提供div。这里你可以看几个例子。我相信如果你需要用宽度来计算高度就足够了