简体   繁体   English

带有NgsScrollReveal的Angular 7 ExpressionChangedAfterItHaHasBeenCheckedError

[英]Angular 7 ExpressionChangedAfterItHasBeenCheckedError with NgsScrollReveal

I am using ngScrollReveal, which causes a re-render every scroll event. 我正在使用ngScrollReveal,它会导致每个滚动事件重新呈现。 I am calling a function through the HTML like follows: 我正在通过HTML调用函数,如下所示:

<component [alternate]="toggleAlternate()">

The definition of toggleAlternate() looks like: toggleAlternate()的定义如下所示:

toggleAlternate() {
  this.alternate = !this.alternate;
  return this.alternate;
}

However, I get the following error on every scroll event: 但是,在每个滚动事件上都会出现以下错误:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. 错误错误:ExpressionChangedAfterItHasBeenCheckedError:检查表达式后,表达式已更改。 Previous value: 'alternate: false'. 先前的值:“ alternate:false”。 Current value: 'alternate: true'. 当前值:“ alternate:true”。

I have tried a couple of solutions such as injecting ChangeDetectorRef and calling detectChanges() in the toggleAlternate() method, however, that did not fix the error. 我尝试了几种解决方案,例如注入ChangeDetectorRef并在toggleAlternate()方法中调用detectChanges(),但是并没有解决错误。 I am new to Angular and am not sure what I can do to fix this. 我是Angular的新手,不确定如何解决此问题。

Is there a way to not call the toggleAlternate() method on every render? 有没有一种方法可以在每个渲染器上不调用toggleAlternate()方法?

Currently, the UI is working fine, but I would like to remove the console errors. 目前,用户界面运行良好,但我想删除控制台错误。

Update 更新

I am trying to make my work experience as a timeline in which every entry is alternate to the previous one. 我试图将自己的工作经历作为一个时间表,在该时间表中,每个条目都可以替代上一个条目。

the following is where toggleAlternate() is called: 以下是调用toggleAlternate()位置:

<app-work-ex-position *ngFor="let job of year[Object.keys(year)[0]].jobs" [job]=job [alternate]="toggleAlternate()">
</app-work-ex-position>

this is how the <app-work-ex-position /> component looks like: 这是<app-work-ex-position />组件的样子:

<app-work-ex-timeline-entry (expand)="onExpandEntry($event)" class="{{alternate ? 'alternate' : ''}}">

<app-work-ex-timeline-entry-dot class="{{isExpanded ? 'primary-circle' : 'primary-circle circle-not-expanded'}}"
                      [size]="30"
                      [isAlternate]="alternate">
</app-work-ex-timeline-entry-dot>
</app-work-ex-timeline-entry>

Based on what the value of alternate is returned from the parent component i set the css class. 基于从父组件返回的alter值,我设置了CSS类。

You should never call a function that changes component state from the HTML. 您永远不要调用从HTML更改组件状态的函数。 This function will be called every change detection cycle and thus the component's state can never stabilise. 在每个更改检测周期都会调用此函数,因此组件的状态永远无法稳定。

It seems that you want to set a CSS class within the component for every other instance. 似乎您想在组件中为所有其他实例设置CSS类。 For this purpose you should use the even and odd variables exposed by *ngFor as can be found in the documentation . 为此,您应该使用*ngFor公开的evenodd变量,可以在文档中找到它们。

Your code would need to be adapted as follows: 您的代码需要进行如下修改:

<app-work-ex-position 
    *ngFor="let job of year[Object.keys(year)[0]].jobs; even as isEven" 
    [isAlternate]="isEven">
</app-work-ex-position>
set isAlternate(value: boolean) {
  this.alternate = value;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM