首页 > 解决方案 > 无法将无效/有效状态传递给自定义表单组件

问题描述

在我的角度应用程序中,我使用自定义时间选择器组件(它由带有输入的材料表单字段和两个用于增加/减少时间的按钮组成)。它实现了 ControlValueAccessor,所以我可以将它与 ngModel/formControl 一起使用。问题是,当父表单中的表单控件无效时,它不会显示无效。它只是不会传播到自定义输入组件。如何绑定到附加到整个组件的表单控件,从而更改输入的有效/无效状态?

我试图在构造函数中注入 ngControl,但这会导致循环依赖错误。知道如何将 formControl 中的错误绑定到组件内部的输入吗?我的代码如下所示:timepicker.ts:

@Component({
  selector: 'app-timepicker',
  templateUrl: './timepicker.component.html',
  styleUrls: ['./timepicker.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi:true,
      useExisting: TimepickerComponent
    }
  ]
})
export class TimepickerComponent implements ControlValueAccessor{

  constructor(){
  }

  @Output() timeChanged: EventEmitter<string>=new EventEmitter();
  value;
  @Input() label:string;
  onChange = (value) => {};
  onTouched = () => {};
  touched = false;
  disabled = false;


  writeValue(value){
    this.value=value;
  }

  registerOnChange(onChange: any) {
    this.onChange=onChange;
  }

  registerOnTouched(onTouched: any) {
    this.onTouched = onTouched;
  }

  setDisabledState(disabled: boolean) {
    this.disabled = disabled;
  }


  changeTime(event){
    const timeArray=event.target.value.split(":");
    console.log(timeArray);
    const hours=parseInt(timeArray[0]);
    const minutes=parseInt(timeArray[1]);
    this.timeChanged.emit(this.value);
    this.value=this.roundMinutes(hours,minutes);
    this.onChange(this.value)

  }

  changeMinutes(minutesToAdd){
    ...
  }

  private roundMinutes(hours,minutes){
    ...
  }

  markAsTouched() {
    if (!this.touched) {
      this.onTouched();
      this.touched = true;
    }
  }
}

时间选择器模板:

<div fxLayoutAlign="center center">
  <mat-form-field appearance="fill" class="no-padding no-underline">
    <mat-label>{{label}}</mat-label>
    <input matInput step="900" type="time" [ngModel]="value" readonly (change)="changeTime($event)">
  </mat-form-field>
  <button [disableRipple]="true" mat-icon-button color="primary" (click)="changeMinutes(15)">
    <mat-icon>add</mat-icon>
  </button>
  <button [disableRipple]="true" mat-icon-button color="primary" (click)="changeMinutes(-15)">
    <mat-icon>remove</mat-icon>
  </button>
</div>

父表单html:

<mat-card class="records-card">
  <mat-card-content [formGroup]="deedsForm">
    <ng-container *ngFor="let group of deedsFormArray.controls;let i = index" formArrayName="deeds">
      <div [formGroupName]="i"  fxLayout fxLayoutAlign="center center" fxLayoutGap="10px">
        <app-timepicker  formControlName="startTime"></app-timepicker>
        <app-timepicker   formControlName="endTime"></app-timepicker>
      </div>
    </ng-container>
  </mat-card-content>
</mat-card>

标签: javascriptangulartypescriptangular-material

解决方案


推荐阅读