如何修复ExpressionChangedAfterItHasBeenCheckedError

时间:2019-11-22 22:45:49

标签: html angular typescript

我有一个带有mat-autocomplete元素的应用程序,其中有城市作为选项。城市来自数据库。有一个添加输入元素的按钮。这是通过使div元素具有* ngFor属性来实现的,该属性会循环访问component.ts文件中的属性。单击添加按钮时,会将元素添加到属性中,并因此添加输入。但是,当我在第一个输入中键入城市名称,然后尝试添加输入元素时,我得到了ExpressionChangedAfterItHaHasBeenCheckedError。

我发现很多人都遇到了这个错误,但是我已经尝试了所有给定的解决方案,但是其中的一个似乎都不起作用。喜欢:

        startWith(''),
        delay(0),
        map(value => this._filter(value))
      );
ngAfterViewInit(){
    this.cd.detectChanges();
  }
var request = new CityCreationRequestModel();
    request.name = "";
    Promise.resolve(null).then(() => this.reportGroupCreationRequest.cityReportGroups.push(request));

并尝试超时。

这是我的html文件:

<div class="container">
    <mat-card>
        <mat-card-header>
            <mat-card-title>Voeg een reportgroep toe</mat-card-title>
            <mat-card-subtitle>Geef emailadressen op die verbonden worden met de rapporten van bepaalde steden</mat-card-subtitle>
        </mat-card-header>
        <mat-card-content>
                <form (ngSubmit)="onSubmit()" #addReportGroup="ngForm" *ngIf="!isLoading">

                    <div *ngFor="let city of reportGroupCreationRequest.cityReportGroups" class="form-row">
                      <mat-form-field>
                          <input placeholder="Stad" required [(ngModel)]="city.name" type="text" matInput [formControl]="myControl" [matAutocomplete]="auto" name="cityInput">
                          <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
                              <mat-option *ngFor="let cityName of filteredOptions | async" [value]="cityName">
                                {{ cityName }}
                              </mat-option>
                            </mat-autocomplete>
                      </mat-form-field>
                      </div>

                      <button mat-raised-button (click)="addCity()">Voeg een stad toe</button>

                        <div class="form-row">
                          <button mat-raised-button type="submit" [disabled]="!addReportGroup.valid" class="submitButton">Opslagen</button>
                        </div>
                      </form>
                      <mat-spinner [style.display]="isLoading ? 'block' : 'none'"></mat-spinner>
        </mat-card-content>
    </mat-card>

这是我的.ts文件:

如果是mat-autocomplete元素,则为过滤器

export class AddReportGroupComponent implements OnInit {

  myControl = new FormControl();
  filteredOptions: Observable<string[]>;

  public reportGroupCreationRequest: ReportGroupCreationRequestModel = new ReportGroupCreationRequestModel();

  public cities: Array<CityResponseModel>;
  public cityNames: Array<string>;
  private isLoading: boolean;

  constructor(private reportGroupService: ReportGroupService,
    private cd: ChangeDetectorRef) { 
  }

  ngOnInit() {
    this.isLoading = true;
    this.reportGroupService.getCities().subscribe(result => {
      this.cities = result;
      this.cities.sort((a,b) => a.name.localeCompare(b.name));
      this.cityNames = this.cities.map(c=>c.name);
    }).add(()=> {
      this.isLoading = false;
      this.filteredOptions = this.myControl.valueChanges.pipe(
        startWith(''),
        delay(0),
        map(value => this._filter(value))
      );
    });

    this.reportGroupCreationRequest.cityReportGroups.push(new CityCreationRequestModel());
    this.reportGroupCreationRequest.emailReportGroups.push(new EmailCreationRequestModel());
  }

//doesn't seem to do anything
  ngAfterViewInit(){
    this.cd.detectChanges();
  }

  private _filter(value: string): string[] {
    const filterValue = value.toLowerCase();

    return this.cityNames.filter(cn => cn.toLowerCase().indexOf(filterValue) === 0);
  }

  addCity(){
    var request = new CityCreationRequestModel();
    request.name = "";
    Promise.resolve(null).then(() => this.reportGroupCreationRequest.cityReportGroups.push(request));
  }

这些是我使用的模型:

export class ReportGroupCreationRequestModel {
    public cityReportGroups: Array<CityCreationRequestModel> = new Array<CityCreationRequestModel>();
    public emailReportGroups: Array<EmailCreationRequestModel> = new Array<EmailCreationRequestModel>();

}
export class CityCreationRequestModel {
    public name: string;
}

预先感谢

我为遇到的问题找到了解决方案:

我同时使用了[[ngModel)]和[FormsControl],显然[[ngModel)]是问题的一部分,所以我只使用了[FormsControl],错误消失了。

addCity(){
    this.reportGroupCreationRequest.cityReportGroups[this.reportGroupCreationRequest.cityReportGroups.length - 1].name = this.myControl.value;
    Promise.resolve(null).then(() => this.reportGroupCreationRequest.cityReportGroups.push(new CityCreationRequestModel()));
  }
<div *ngFor="let city of reportGroupCreationRequest.cityReportGroups" class="form-row">
                      <mat-form-field>
                          <input placeholder="Stad" required type="text" matInput [formControl]="myControl" [matAutocomplete]="auto" name="cityInput">
                          <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
                              <mat-option *ngFor="let cityName of filteredOptions | async" [value]="cityName">
                                {{ cityName }}
                              </mat-option>
                            </mat-autocomplete>
                      </mat-form-field>
                      </div>

0 个答案:

没有答案