如何将角形材料形式包装到组件中,并将其作为formControl元素暴露给FormGroup

时间:2019-02-25 13:29:50

标签: javascript angular typescript angular2-forms angular-reactive-forms

我试图将一个组件(例如称为custom-input)封装为基于Angular材质组件的formControl元素,以包含以下内容:

<mat-form-field >
  <input
    matInput
    [formControl]="inputField"
    formControlName="{{ name }}"
    name="{{ name }}"
    maxlength="{{ maxlength }}"
    placeholder="{{ name | translate }}"
    required
  />
  <mat-error *ngIf="inputField.errors">{{
    this.validationService.getErrorMsg(inputField.errors)
  }}</mat-error>
</mat-form-field>

现在此组件可以使用所需的功能 ,但无法使用formControlName属性(如普通输入或matInput )绑定到formGroup(例如以下示例) ,它直接绑定到formGroup而不出现问题)

<input
  matInput
  formControlName="inputField123"
  placeholder="{{ 'testInput' | translate }}"
  required
/>

问题是如何使上述组成的组件绑定为formGroup中的formControl元素?我应该实现或公开哪些功能以提供此功能?

我应该使用ControlValueAccessor还是对材料输入组件使用更好的方法?

1 个答案:

答案 0 :(得分:0)

经过长时间的搜索,主要是因为建议将ControlValueAccessor用于原始的html部件(例如输入左右,而不是材料部件,我认为可能有一些更容易的包装技术)

我最终发现,我们可以按照建议实施ControlValueAccessor,或者由于这是一个输入字段,因此我们可以像这样使用DefaultValueAccessor

@Component({
  selector: 'app-test-input',
  templateUrl: './test-input.component.html',
  styleUrls: ['./test-input.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => testInputComponent),
      multi: true
    }
  ]
})
export class testInputComponent implements ControlValueAccessor {
  @Input() name = '';
  @Input() maxlength = 250;
  @Input() width = 30;

  @ViewChild(DefaultValueAccessor) valueAccessor: DefaultValueAccessor;

  writeValue(obj: any) {
    this.valueAccessor.writeValue(obj);
  }

  registerOnChange(fn: any) {
    this.valueAccessor.registerOnChange(fn);
  }

  registerOnTouched(fn: any) {
    this.valueAccessor.registerOnTouched(fn);
  }

  setDisabledState(isDisabled: boolean) {
    this.valueAccessor.setDisabledState(isDisabled);
  }

  constructor(public dataService: DataService) {
  }

}

html部分是这样的:

<mat-form-field fxFlex="100" >
  <input
    matInput
    formControlName="{{ name }}"
    maxlength="{{ maxlength }}"
    placeholder="{{ name | translate }}"
    required
  />
  <mat-error *ngIf="matInputSelector.errors">{{
    this.dataService.getErrorMsg(matInputSelector.errors)
  }}</mat-error>
</mat-form-field>

注意

如果我使用formControlName="{{ name }}"可以将控件绑定到formGroup,但是不能使用formControl属性绑定到组件的错误部分

即:我可以使用:

1- formControl(可以控制错误部分)

OR

2-使用formControlName(绑定到外部formGroup,但无法控制错误部分)

因此,如果有人有更好的答案,请发布它以帮助所有人。