角度和错误:ExpressionChangedAfterItHasBeenCheckedError

时间:2020-10-23 09:49:44

标签: angular

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

ExpressionChangedAfterItHaHasBeenCheckedError:检查表达式后,表达式已更改。先前的值:“ 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行中显示相同的图标(但实际上每行都不同)

2 个答案:

答案 0 :(得分:1)

角度运行在间隔或事件中检测组件的变化。您遇到的情况是,您在角度运行变更检测之后和下一个变更检测周期之前对数据/视图进行了更改。

因此,角度将介于两者之间。该代码可以工作,但是不能保证它会100%地工作。

最容易产生错误的行是imgUrl
<img *ngIf="imgURL" [src]="imgURL" height="50" width="50" alt="logo">

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

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

答案 1 :(得分:0)

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

<Application x:Class="UI.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:system="clr-namespace:System;assembly=mscorlib"
         xmlns:vm="clr-namespace:UI.ViewModel"
         xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
         xmlns:local="clr-namespace:UI"
         StartupUri="MainWindow.xaml">

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
            <!-- Accent and AppTheme setting -->
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Teal.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Controls.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml" />
            <!-- Icons -->
            <ResourceDictionary x:Name="IconsDictionary" Source="Resources/Dictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <system:Double x:Key="WindowTitleFontSize">16</system:Double>
        <FontFamily x:Key="HeaderFontFamily">Segoe UI</FontFamily>
        <vm:ViewModelLocator x:Key="MainLocator"/>
    </ResourceDictionary>
</Application.Resources>

模板中的一些小变化:

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