【问题标题】:Angular and ERROR: ExpressionChangedAfterItHasBeenCheckedError角度和错误:ExpressionChangedAfterItHasBeenCheckedError
【发布时间】:2020-10-23 09:49:44
【问题描述】:

我不知道如何解决我的问题。我有一个包含行的表 在其中一个列中应该显示一些图标(从后端服务获取的数据),但我在控制台中收到以下错误:

ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'ngIf:未定义'。当前值:'ngIf: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAk

然后我添加了

     setLogoImage(logo: any) {
    if (logo) {
      this.imgURL = 'data:image/jpeg;base64,' + logo;
    }
  }

  ngAfterViewChecked(): void {
    this.cdRef.detectChanges();
  }

还有我的模板:

 <ng-template let-columns="columns" let-rowData pTemplate="body">
    <tr>
      <td class="ui-resizable-column">{{ rowData['name'] || '' }}</td>
      <td class="ui-resizable-column">{{ rowData['active'] | yesNoBoolean }}</td>
      <td class="ui-resizable-column">
       //some data
      </td>
      <td class="ui-resizable-column">{{ setLogoImage(rowData['logo']) }}<img *ngIf="imgURL"
                                                                              [src]="imgURL" height="50"
                                                                              width="50" alt="logo"></td>
      <td class...

目前图标显示没有任何错误,但顺序错误!一切都向下移动一排!你知道如何解决这个问题吗?

更新

嗯,它不起作用。修改后:

   export class FrameworkSearchResultsComponent extends PaginationComponent implements OnInit, AfterViewChecked {
    
   constructor(private cdRef: ChangeDetectorRef) {
    super();
  }

  ngOnInit() {
    this.pagination.sort = 'name,ASC';
    this.setPage.subscribe(val => {
      if (this.table) {
        this.table.first = val;
      }
    });
  }
    
    
    setLogoImage(logo: any) {
        setTimeout(() => {
          if (logo) {
            this.imgURL = 'data:image/jpeg;base64,' + logo;
          }
        }, 100);
      }
    
      ngAfterViewChecked(): void {
        this.cdRef.detectChanges();
      }

我的图标经常闪烁并且显示错误的图标,例如。第 1 行和第 2 行显示相同的图标(但实际上每行不同)

【问题讨论】:

  • 您介意在问题中显示setLogoImage(logo: any) 上方函数的其余部分吗?可能有机会推迟 imgURL 分配的更改

标签: angular


【解决方案1】:

Angular 在间隔或事件上对组件运行更改检测。在您的情况下发生的情况是,您在 Angular 运行它的更改检测之后和下一个更改检测周期之前对数据/视图进行了更改。

因此,角度将改变您在两者之间所做的更改。代码可以工作,但不能保证 100% 的时间都可以工作。

与您产生错误的行很可能是imgUrl:
&lt;img *ngIf="imgURL" [src]="imgURL" height="50" width="50" alt="logo"&gt;

您需要在 ngOnInit 等更改挂钩中分配 imgUrl 或将其封装在 settimeout 中以将更改延迟 50 到 100 毫秒。然后,您将不需要手动运行更改检测

setLogoImage(logo: any) {
    setTimeout(()=> {
     if (logo) {
      this.imgURL = 'data:image/jpeg;base64,' + logo;
    }
  },100);
}

【讨论】:

  • 更新了我的代码...不幸的是不起作用...也许我做错了什么
  • 你说得对,问题与 imgUrl 有关...当我从模板中删除 *ngIf="imgURL" 时,图标会以良好的顺序显示,但随后会在每一行中显示图标, 什么是不可取的
  • @Matley 将超时时间从 100 增加到 200,然后继续增加直到问题消失
  • “然后不断增加直到问题消失”是什么意思?
  • 如果我设置延迟,您的第一个 setTimeout 解决方案对我不起作用。到 500 然后我必须等待几秒钟直到我的页面完全加载(并且我的加载微调器显示很长时间)......并且在加载所有图标后顺序仍然错误......所以也许我应该以某种方式分配某个钩子中的 imgURL 变量?
【解决方案2】:

好的,我通过将方法 setLogoImage 更改为 getLogoImage 解决了我的问题:

  getLogoImage(logo: any) {
    if (logo) {
      return 'data:image/jpeg;base64,' + logo;
    }
  }

还有一些模板的小改动:

<td class="ui-resizable-column"><img *ngIf="rowData['logo']"
                                           [src]="getLogoImage(rowData['logo'])" height="50"
                                           width="50" alt="logo"></td>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 2021-07-22
    • 2019-01-06
    • 2018-09-17
    • 2017-10-10
    • 1970-01-01
    相关资源
    最近更新 更多