Angular 分离组件中的表单元素给出 FormGroup 错误
Angular form element in separated component gives FormGroup error
我有一个用 Angular Material 制作的表单元素,它是一个自动完成的国家 selectbox:
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
在 ngOnInit
中,我调用了一个 API 并填充了 filteredOptions。
因为我要以多种形式使用这个选择器,所以我想制作它的一个组件。一旦我将代码移动到我得到的组件:
SelectCountryComponent.html:2 ERROR Error: 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).
即使我在 FormGroup 中使用我的组件,它仍然会出现此错误。创建包含 formControl 的组件的正确方法是什么?
select-country.component.ts
@Component({
selector: 'app-select-country',
templateUrl: './select-country.component.html',
styleUrls: ['./select-country.component.css']
})
export class SelectCountryComponent implements OnInit {
countryFormGroup = new FormGroup({
country: new FormControl('')
});
options: Country[];
filteredOptions: Observable<Country[]>;
constructor(public api: ApiService) {
}
ngOnInit() {
this.api.get('country').subscribe(res => {
console.log(res);
this.options = res;
this.filteredOptions = this.countryFormGroup.get('country').valueChanges.pipe(
startWith<string | Country>(''),
map(value => (typeof value === 'string' ? value : value['name'])),
map(name => name ? this._filter(name) : this.options ? this.options.slice() : [])
);
});
}
displayFn(country?: Country): string | undefined {
return country ? country.name : undefined;
}
private _filter(name: string): Country[] {
const filterValue = name.toLowerCase();
return this.options.filter(
option => option.name.toLowerCase().indexOf(filterValue) === 0
);
}
}
select-country.component.html
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
用 div 或 form 和 [formGroup]=[=17= 包裹你的 mat-form-field ].您需要将实例化的 formGroup 绑定到模板。
<div [formGroup]="countryFormGroup">
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
你的情况:
<form [formGroup]="countryFormGroup" (ngSubmit)="onSubmit()">
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
</mat-form-field>
</form>
您需要通过 [formGroup]="countryFormGroup"
将 countryFormGroup 与表单绑定,并在其中使用 formControlName
。
为了使您的代码更简洁,您可以在 HTML
中使用管道过滤选项
我有一个用 Angular Material 制作的表单元素,它是一个自动完成的国家 selectbox:
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
在 ngOnInit
中,我调用了一个 API 并填充了 filteredOptions。
因为我要以多种形式使用这个选择器,所以我想制作它的一个组件。一旦我将代码移动到我得到的组件:
SelectCountryComponent.html:2 ERROR Error: 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).
即使我在 FormGroup 中使用我的组件,它仍然会出现此错误。创建包含 formControl 的组件的正确方法是什么?
select-country.component.ts
@Component({
selector: 'app-select-country',
templateUrl: './select-country.component.html',
styleUrls: ['./select-country.component.css']
})
export class SelectCountryComponent implements OnInit {
countryFormGroup = new FormGroup({
country: new FormControl('')
});
options: Country[];
filteredOptions: Observable<Country[]>;
constructor(public api: ApiService) {
}
ngOnInit() {
this.api.get('country').subscribe(res => {
console.log(res);
this.options = res;
this.filteredOptions = this.countryFormGroup.get('country').valueChanges.pipe(
startWith<string | Country>(''),
map(value => (typeof value === 'string' ? value : value['name'])),
map(name => name ? this._filter(name) : this.options ? this.options.slice() : [])
);
});
}
displayFn(country?: Country): string | undefined {
return country ? country.name : undefined;
}
private _filter(name: string): Country[] {
const filterValue = name.toLowerCase();
return this.options.filter(
option => option.name.toLowerCase().indexOf(filterValue) === 0
);
}
}
select-country.component.html
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
用 div 或 form 和 [formGroup]=[=17= 包裹你的 mat-form-field ].您需要将实例化的 formGroup 绑定到模板。
<div [formGroup]="countryFormGroup">
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
你的情况:
<form [formGroup]="countryFormGroup" (ngSubmit)="onSubmit()">
<mat-form-field>
<input type="text" placeholder="Country" aria-label="Number" matInput formControlName="country" [matAutocomplete]="auto">
</mat-form-field>
</form>
您需要通过 [formGroup]="countryFormGroup"
将 countryFormGroup 与表单绑定,并在其中使用 formControlName
。
为了使您的代码更简洁,您可以在 HTML
中使用管道过滤选项