1

这是在我的 html 文件中:

  <div id="my-div" [ngClass]="hasSetting ? 'my-container' : 'opacity-div my-container'">    
    <dx-load-panel
      #loadPanel
      [(visible)]="!hasSetting" >
    </dx-load-panel>
  </div>

这是我的组件:

export class TurnoverWidgetComponent {

  departments: DropdownOption[] = [];
  hasSetting: boolean;

  constructor(
    private myService: MyService
  ) {

    forkJoin(
      this.myService.hasSetting(),
      this.myService.getDepartments()
    ).subscribe(
      ([hasSetting, departments]) => {
        this.hasSetting = hasSetting;

          this.departments = departments.map(item => {
            return {
              id: item.id,
              name: item.name
            }
          });
      }
    );
  }
}

我收到错误错误:检查后表达式已更改-在构造函数中,从真到假,反之亦然。根据我的研究,此错误发生在组件初始化后发生的事件中,但是我没有此类事件,我的更改发生在构造函数中。我试着把它放在 oninit 事件中,同样的事情发生了。

4

3 回答 3

0

我认为您应该在设置超时下提供您的逻辑。这将解决您的问题。

ngAfterViewInit() {
     forkJoin(
      this.myService.hasSetting(),
      this.myService.getDepartments()
    ).subscribe(
      ([hasSetting, departments]) => {
        
    setTimeout(() => {
       this.hasSetting = hasSetting;
    },200);
          this.departments = departments.map(item => {
            return {
              id: item.id,
              name: item.name
            }
          });
      }
    );
于 2020-08-12T21:01:35.790 回答
0

它发生在组件已经检查更新并想要更新视觉效果时,并且在更新之前再次检查并看到数据不一样......非常烦人。

但你可以稍微改变你的策略来摆脱它(我希望。我没有测试过)

你不需要订阅你的数据,让异步管道来做,因为它会同时使用数据并且当你改变到另一个路由时也会取消订阅,只需使用运算符以你喜欢的方式塑造数据并将其提供给html。

  data$: Observable<{hasSetting: boolean; departments: DropdownOption[] }>
  constructor(
    private myService: MyService
  ) {

    this.data$ = forkJoin(
      this.myService.hasSetting(),
      this.myService.getDepartments()
    ).pipe(map(x=>{
      return {
        hasSetting: x[0],
        departments: x[1]
      }
    }))
  }
  <div *ngIf="data$ | async as data" [ngClass]="data.hasSetting ? 'my-container' : 'opacity-div my-container'">    
    <dx-load-panel
      #loadPanel
      [visible]="!hasSetting" >
    </dx-load-panel>
  </div>
于 2020-08-12T21:40:11.030 回答
0

您需要了解,当我们从它得到答案时,我们将进行 http 调用并更改组件变量。在开发模式下,Angular 会调用两次更改检测来检查值是否未更改,以确保代码不会出现意外行为。这里 angular 抱怨在第一次检查组件值之后值已经更改。

这是更新的代码,以确保在我们在 http 回调中更改它后 Angular 检测到更改:

    export class TurnoverWidgetComponent implementes OnInit {
    
      departments: DropdownOption[] = [];
      hasSetting: boolean;
    
      constructor(
        private myService: MyService,
        private cd: ChangeDetectorRef,
      ) {}

      ngOnInit() {

        forkJoin(
          this.myService.hasSetting(),
          this.myService.getDepartments()
        ).subscribe(
          ([hasSetting, departments]) => {
            this.hasSetting = hasSetting;
    
              this.departments = departments.map(item => {
                return {
                  id: item.id,
                  name: item.name
                }
              });
            this.cd.detectChanges(); // this will tell angular that we changed something and explicitly invoke change detection.
          }
        );
     }
    }
于 2020-08-13T03:30:45.480 回答