首页 > 解决方案 > setErrors({ backend: true }) 不起作用,因为 formcontrol 具有值或由于 ngfor 循环

问题描述

我相信我的setErrors功能不起作用,因为 formcontrol 具有价值 product.component.ts

  ngAfterViewInit() {
    this.isPriceErrorSub = this.store.select(getCreateProductsError(this.index, 'isPriceError')).subscribe(err => {
      console.log(err);
      if(err) {
        this.eurosFormControl.setErrors({ backend: true });
        this.centsFormControl.setErrors({ backend: true });
        this.chaschan.markForCheck();
      }
    });
    this.isAmountErrorSub = this.store.select(getCreateProductsError(this.index, 'isAmountError')).subscribe(res => {
      if (res) {
        console.log('jasfnjafn')
        this.amountFormControl.setErrors({ backend: true })
        this.chaschan.markForCheck();
        this.chaschan.detectChanges();
      }
    });
    this.isDescriptionErrorSub = this.store.select(getCreateProductsError(this.index, 'isDescriptionError')).subscribe(res => {
      console.log(res);
      if (res) {
        this.descriptionFormControl.markAsTouched();
        this.descriptionFormControl.setErrors({ backend: true });
        this.chaschan.markForCheck();
      }
    })
  }
  constructor(
    private chaschan: ChangeDetectorRef,
    private store: Store
  ) {
    this.index = 0;
    this.product = {
      euros: 0,
      cents: 0,
      amount: 0,
      description: '',
    }
    this.errorStateMatcher = new MyErrorStateMatcher();
    this.euros = 0;
    this.eurosFormControl = new FormControl(this.product.euros, [
      Validators.required
    ]);
    this.cents = 0;
    this.centsFormControl = new FormControl(this.product.cents, [
      Validators.required
    ])
    this.amount = 0;
    this.amountFormControl = new FormControl(this.product.amount, [
      Validators.required,
      Validators.min(1)
    ])
    this.description = '';
    this.descriptionFormControl = new FormControl(this.product.description, [
      Validators.required
    ]);

    this.productsCount = this.store.select(getCreateProductsCount);
    this.isErrorSub = of().subscribe();
    this.isGrabProductsSub = of().subscribe();
    this.isPriceErrorSub = of().subscribe();
    this.isAmountErrorSub = of().subscribe();
    this.isDescriptionErrorSub = of().subscribe();
   }

product.component.html

<table class="full-width" style="table-layout: fixed;">
  <tr>
    <td>
      <mat-form-field class="full-width"><input matInput disabled placeholder="{{ 'Product ' + (index + 1) }}" value="Price" type="text"></mat-form-field>
    </td>
    <td style="padding-right: 8px;">
      <mat-form-field class="full-width" style="text-align: end;">
        <input matInput [formControl]="eurosFormControl"  [(ngModel)]="euros" [errorStateMatcher]="errorStateMatcher" placeholder="€ 0," type="number">
        <mat-error *ngIf="eurosFormControl.hasError('backend') || centsFormControl.hasError('backend')">
          Price is required
        </mat-error>
      </mat-form-field>

    </td>
    <td>
      <mat-form-field class="full-width">
        <input [formControl]="centsFormControl"  [(ngModel)]="cents" [errorStateMatcher]="errorStateMatcher" matInput placeholder="00" type="number">
      </mat-form-field>
    </td>
  </tr>
</table>
<mat-form-field class="full-width">
  <input type="text" matInput placeholder="Amount" [errorStateMatcher]="errorStateMatcher"  [formControl]="amountFormControl" [(ngModel)]="amount">
  <mat-error *ngIf="amountFormControl.hasError('backend')">
    Amount is required
  </mat-error>
</mat-form-field>
<mat-form-field class="full-width">
  <textarea matInput placeholder="Description"  [formControl]="descriptionFormControl" [errorStateMatcher]="errorStateMatcher" [(ngModel)]="description"  rows="4">
  </textarea>
  <mat-error *ngIf="descriptionFormControl.hasError('backend')">
    Description is required
  </mat-error>
  <button mat-button matSuffix *ngIf="(productsCount | async) == (index + 1)" (click)="add()">new</button>
  <button mat-button matSuffix *ngIf="(productsCount | async)! > (index + 1)" (click)="change()">change</button>
  <button mat-button matSuffix *ngIf="index > 0" (click)="clear()"><mat-icon>clear</mat-icon></button>
</mat-form-field>

因为 decriptionFormControl 变成红色,但是 amountFormControl、eurosFormControl 和 centsFormControl 不会同时 product.component.html 在 ngForLoop 中呈现

create.component.html

<mat-toolbar>
  <button mat-button routerLink="/account">Account</button>
  <span class="spacer"></span>
  <button mat-button >Logout</button>
</mat-toolbar>
<section class="hero is-fullheight-with-navbar is-dark is-bold">
  <div class="hero-body">
    <div class="container has-text-centered">
      <p class="title" [@stateSlide]="titleState | async">Create a new invoice</p>
      <p class="subtitle" [@stateSlide]="subtitleState | async">Please give us information about the reciever</p>
        <mat-slide-toggle [(ngModel)]="isIndividual">
          Individual ?
        </mat-slide-toggle>
        <mat-form-field class="full-width" *ngIf="isIndividual" @transformEnterFromLeftLeaveToRight>
          <input matInput
          placeholder="Firstname"
          [formControl]="firstNameFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="firstName"
          type="text">
          <mat-error *ngIf="firstNameFormControl.hasError('required')">
            Firstname is required
          </mat-error>
        </mat-form-field>
        <mat-form-field class="full-width" *ngIf="isIndividual" @transformEnterFromRightLeaveToLeft>
          <input matInput
          placeholder="Lastname"
          [formControl]="lastNameFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="lastName"
          type="text">
          <mat-error *ngIf="lastNameFormControl.hasError('required')">
            Lastname is required
          </mat-error>
        </mat-form-field>
        <mat-form-field class="full-width" @transformEnterFromLeftLeaveToRight>
          <input matInput
          placeholder="Company"
          [formControl]="companyFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="company"
          type="text">
          <mat-error *ngIf="companyFormControl.hasError('required')">
            Company is required
          </mat-error>
        </mat-form-field>
        <mat-form-field class="full-width" @transformEnterFromRightLeaveToLeft>
          <input matInput
          placeholder="Address"
          [formControl]="addressFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="address"
          type="text">
          <mat-error *ngIf="addressFormControl.hasError('required')">
            Address is required
          </mat-error>
        </mat-form-field>
        <mat-form-field class="full-width" @transformEnterFromLeftLeaveToRight>
          <input matInput
          placeholder="Number"
          [formControl]="numberFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="number"
          type="number">
          <mat-error *ngIf="numberFormControl.hasError('required')">
            Number is required
          </mat-error>
        </mat-form-field>
        <mat-form-field class="full-width" @transformEnterFromRightLeaveToLeft>
          <input matInput
          placeholder="Zipcode"
          [formControl]="zipCodeFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="zipCode"
          type="text">
          <mat-error *ngIf="zipCodeFormControl.hasError('required')">
            Address is required
          </mat-error>
        </mat-form-field>
        <mat-form-field class="full-width" @transformEnterFromLeftLeaveToRight>
          <input matInput
          placeholder="City"
          [formControl]="cityFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="city"
          type="text">
          <mat-error *ngIf="cityFormControl.hasError('required')">
            City is required
          </mat-error>
        </mat-form-field>
        <mat-form-field class="full-width" @transformEnterFromRightLeaveToLeft>
          <input matInput
          placeholder="Country"
          [formControl]="countryFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="country"
          type="text">
          <mat-error *ngIf="countryFormControl.hasError('required')">
            Country is required
          </mat-error>
        </mat-form-field>

        <mat-form-field class="full-width" @transformEnterFromLeftLeaveToRight>
          <input matInput
          placeholder="VAT-number"
          [formControl]="VATNumberFormControl"
          [errorStateMatcher]="errorStateMatcher"
          [(ngModel)]="VATNumber"
          type="text">
          <mat-error *ngIf="VATNumberFormControl.hasError('required')">
            VAT-number is required
          </mat-error>
        </mat-form-field>
          <app-product  *ngFor="let product of (products | async); let i = index" [index]="i" [product]="product"></app-product>
        <button mat-raised-button class="full-width" (click)="submit()" *ngIf="(productsCount | async)! > 0">submit</button>
      </div>
  </div>
</section>

标签: angulartypescriptngforform-controlangular12

解决方案


因为您必须更改产品this.amountFormControl.markAsTouched()


推荐阅读