尝试在Angular中创建可重复使用的表单组件时发生错误

时间:2018-10-23 03:15:56

标签: angular

我正在使用Angular Material Select,并且效果很好:

<div [formGroup]="dwellingValues">
<mat-form-field appearance="outline" hideRequiredMarker>
  <mat-label>Dwelling Type</mat-label>
  <mat-select formControlName="typeofDwelling">
    <mat-option>Please Select</mat-option>
    <mat-option *ngFor="let dwellingType of dwellingOptions.dwellingTypes" [value]="dwellingType">
      {{dwellingType}}
    </mat-option>
  </mat-select>
</mat-form-field>
</div>

因为我有很多这样的东西,所以我试图创建一个可重用的组件。

我创建了以下内容:

export class MySelectComponent {
  @Input() formControl: string;
  @Input() label: string;
  @Input() value: string;
  @Input() placeholder: string;
  @Input() items: string[];

  constructor() { }

}

使用以下html

<mat-form-field appearance="outline" hideRequiredMarker>
  <mat-label>{{label}}</mat-label>
  <mat-select placeholder=placeholder formControlName=formControl>
    <mat-option>Please Select</mat-option>
    <mat-option *ngFor="let item of items" [value]="item">
      {{item}}
    </mat-option>
  </mat-select>
</mat-form-field>

我这样称呼它:

<div [formGroup]="dwellingValues">
    <app-my-select [label]="'Dwelling Type'"  [formControl]="'typeofDwelling'" [items]="dwellingOptions.dwellingTypes" ></app-my-select>         
</div>

我遇到以下错误:

No value accessor for form control with unspecified name attribute
formControlName must be used with a parent formGroup directive.  You'll want to add a formGroup directive and pass it an existing FormGroup instance (you can create one in your class).

1 个答案:

答案 0 :(得分:2)

您要传递FormControlName作为输入而不是formControl。您需要获取formControl并将其传递作为输入。

父HTML为

<div [formGroup]="dwellingValues">
 <app-my-select 
  [label]="'Dwelling Type'" 
  [selectFormControl]="typeofDwelling" 
  [items]="dwellingOptions.dwellingTypes">
 </app-my-select>
</div>

最佳实践是将getter用于formControl。 父html为

<div [formGroup]="dwellingValues">
 <app-my-select [label]="'Dwelling Type'" [formControl]="typeofDwelling" [items]="dwellingOptions.dwellingTypes" ></app-my-select>         
</div>

和父控制器中的内容。

public get typeofDwelling(): FormControl {
return this.dwellingValues.get('typeofDwelling') as FormControl;
}

并将formControl输入类型更改为FormControl

export class MySelectComponent {
 @Input() selectFormControl: FormControl;
 @Input() label: string;
 @Input() items: string[];

 constructor() { }

}

和子html as

 <mat-form-field appearance="outline" hideRequiredMarker>
  <mat-label>{{label}}</mat-label>
  <mat-select [formControl]="selectFormControl">
    <mat-option>Please Select</mat-option>
    <mat-option *ngFor="let item of items" [value]="item">
        {{item}}
    </mat-option>
  </mat-select>
 </mat-form-field>

这是此slackblitz

的演示