没有 FormControls 的 FormArray,只有字符串 Angular 2
FormArray without FormControls and just strings Angular 2
我的后端有两个字符串数组,我必须用单个字符串或多个字符串填充它们。但是它们不是键值对。我试图将一个字符串推入其中一个数组,但 运行 导致我没有也不能指定控件:值对。
我的 formArray 看起来像
collections: new FormArray([]),
我的 html 到 select 字符串
<md-select placeholder="Collection">
<md-option (click)="addCollectionId('one')" value="Local">Local</md-option>
<md-option (click)="addCollectionId('two')" value="Music">Music</md-option>
<md-option (click)="addCollectionId('three')" value="Performing Arts">Performing Arts</md-option>
<md-option (click)="addCollectionId('four')" value="Sports">Sports</md-option>
<md-option (click)="addCollectionId('five')" value="Restaurants">Restaurants</md-option>
</md-select>
我将字符串添加到 formArray 的逻辑如下所示:
addCollectionId(id: string) {
const control = <FormArray>this.createCardForm.controls['collections'];
control.push(id);
}
我收到错误“'string' 类型的参数不可分配给 'AbstractControl' 类型的参数”。
由于我无法推送控件:值对而且只能推送 string/strings 如何在仍保持整体形式的情况下将字符串推送到数组?
任何 help/tips/suggestions 将不胜感激。
FormArray
的目的是包含一组 FormControl
或 FormGroup
,以便您可以动态地将输入元素添加到 HTML 表单。我不认为这是你打算做的,普通数组可能适合你的目的。
这是来自文档:
Tracks the value and validity state of an array of FormControl,
FormGroup or FormArray instances. A FormArray aggregates the values of
each child FormControl into an array. It calculates its status by
reducing the statuses of its children.
For example, if one of the
controls in a FormArray is invalid, the entire array becomes invalid.
FormArray is one of the three fundamental building blocks used to
define forms in Angular, along with FormControl and FormGroup.
我假设您已经拥有一个包含所有数据的数据模型。这是我的例子:
/* Defines the product entity */
export interface IProduct {
id: number;
productName: string;
productCode: string;
tags?: string[];
releaseDate: string;
price: number;
description: string;
starRating: number;
imageUrl: string;
}
注意它有一个标签数组。
您的 addCollectionId
方法可以直接更新您的数据模型。
在保存之前,你可以这样做:
let p = Object.assign({}, this.product, this.productForm.value);
它创建了一个新对象,将其分配给我的产品实例中的值(它会设置我的标签数组属性),然后覆盖我的表单中的所有属性。所以它基本上使用任何表单属性更新我的本地产品模型属性。
那么在本例中保存代码将保存p
。
有道理吗?
你可以使用 Reactive Forms API 来实现这个,我也推荐使用 angular formBuilder:
export class SelectOverviewExample {
createCardForm: FormGroup;
foods = [
{value: 'steak-0', viewValue: 'Steak'},
{value: 'pizza-1', viewValue: 'Pizza'},
{value: 'tacos-2', viewValue: 'Tacos'}
];
// inject form builder
constructor(private fb: FormBuilder) {
// add collections form array to your form
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
});
}
// function which pushed new value to collections array
addCollectionId(val) {
const collections = this.createCardForm.get('collections');
// add only once
if (!collections.value.includes(val)) {
collections.push(this.fb.control(val));
}
}
}
这样,您选择的所有值都将添加到表单中,并在 createCardForm.value.collections
数组下可用。
这里是 HTML:
<md-select placeholder="Favorite food">
<md-option [disabled]="createCardForm.value.collections.includes(food.value)"
*ngFor="let food of foods"
[value]="food.value"
(click)="addCollectionId(food.value)">
{{ food.viewValue }}
</md-option>
</md-select>
<pre>{{ createCardForm.value | json }}</pre>
此处更新plunker forked from https://material.angular.io/components/select/overview
更新
这里是仅反应形式的解决方案,没有调用 addCollectionId()
函数。
添加 reactiveCollections 字段到表单组:
constructor(private fb: FormBuilder) {
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
reactiveCollections: null
});
}
将表单组和控件名称添加到 md-select
:
<form [formGroup]="createCardForm">
<md-select placeholder="Favorite food"
multiple="true"
formControlName="reactiveCollections">
<md-option *ngFor="let food of foods" [value]="food.value">
{{ food.viewValue }}
</md-option>
</md-select>
</form>
Plunker也更新了
export class SelectOverviewExample {
createCardForm: FormGroup;
// inject form builder
constructor(private fb: FormBuilder) {
// add collections form array to your form
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
});
}
// get method which return the formArray as control
get collections(): FormArray {
return this.createCardForm.get('collections') as FormArray;
};
// function which pushed new value to collections array
addCollectionId(val) {
// Instead of this use get property
//const collections = this.createCardForm.get('collections');
// add only once
if (!this.collections.value.includes(val)) {
this.collections.push(this.fb.control(val));
}
}
}
我也遇到了 "Property 'push' does not exist on type 'AbstractControl'" 错误,我找到了解决方案,只是删除了 const 并添加了 get 收集方法。
我的后端有两个字符串数组,我必须用单个字符串或多个字符串填充它们。但是它们不是键值对。我试图将一个字符串推入其中一个数组,但 运行 导致我没有也不能指定控件:值对。
我的 formArray 看起来像
collections: new FormArray([]),
我的 html 到 select 字符串
<md-select placeholder="Collection">
<md-option (click)="addCollectionId('one')" value="Local">Local</md-option>
<md-option (click)="addCollectionId('two')" value="Music">Music</md-option>
<md-option (click)="addCollectionId('three')" value="Performing Arts">Performing Arts</md-option>
<md-option (click)="addCollectionId('four')" value="Sports">Sports</md-option>
<md-option (click)="addCollectionId('five')" value="Restaurants">Restaurants</md-option>
</md-select>
我将字符串添加到 formArray 的逻辑如下所示:
addCollectionId(id: string) {
const control = <FormArray>this.createCardForm.controls['collections'];
control.push(id);
}
我收到错误“'string' 类型的参数不可分配给 'AbstractControl' 类型的参数”。
由于我无法推送控件:值对而且只能推送 string/strings 如何在仍保持整体形式的情况下将字符串推送到数组?
任何 help/tips/suggestions 将不胜感激。
FormArray
的目的是包含一组 FormControl
或 FormGroup
,以便您可以动态地将输入元素添加到 HTML 表单。我不认为这是你打算做的,普通数组可能适合你的目的。
这是来自文档:
Tracks the value and validity state of an array of FormControl, FormGroup or FormArray instances. A FormArray aggregates the values of each child FormControl into an array. It calculates its status by reducing the statuses of its children.
For example, if one of the controls in a FormArray is invalid, the entire array becomes invalid. FormArray is one of the three fundamental building blocks used to define forms in Angular, along with FormControl and FormGroup.
我假设您已经拥有一个包含所有数据的数据模型。这是我的例子:
/* Defines the product entity */
export interface IProduct {
id: number;
productName: string;
productCode: string;
tags?: string[];
releaseDate: string;
price: number;
description: string;
starRating: number;
imageUrl: string;
}
注意它有一个标签数组。
您的 addCollectionId
方法可以直接更新您的数据模型。
在保存之前,你可以这样做:
let p = Object.assign({}, this.product, this.productForm.value);
它创建了一个新对象,将其分配给我的产品实例中的值(它会设置我的标签数组属性),然后覆盖我的表单中的所有属性。所以它基本上使用任何表单属性更新我的本地产品模型属性。
那么在本例中保存代码将保存p
。
有道理吗?
你可以使用 Reactive Forms API 来实现这个,我也推荐使用 angular formBuilder:
export class SelectOverviewExample {
createCardForm: FormGroup;
foods = [
{value: 'steak-0', viewValue: 'Steak'},
{value: 'pizza-1', viewValue: 'Pizza'},
{value: 'tacos-2', viewValue: 'Tacos'}
];
// inject form builder
constructor(private fb: FormBuilder) {
// add collections form array to your form
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
});
}
// function which pushed new value to collections array
addCollectionId(val) {
const collections = this.createCardForm.get('collections');
// add only once
if (!collections.value.includes(val)) {
collections.push(this.fb.control(val));
}
}
}
这样,您选择的所有值都将添加到表单中,并在 createCardForm.value.collections
数组下可用。
这里是 HTML:
<md-select placeholder="Favorite food">
<md-option [disabled]="createCardForm.value.collections.includes(food.value)"
*ngFor="let food of foods"
[value]="food.value"
(click)="addCollectionId(food.value)">
{{ food.viewValue }}
</md-option>
</md-select>
<pre>{{ createCardForm.value | json }}</pre>
此处更新plunker forked from https://material.angular.io/components/select/overview
更新
这里是仅反应形式的解决方案,没有调用 addCollectionId()
函数。
添加 reactiveCollections 字段到表单组:
constructor(private fb: FormBuilder) {
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
reactiveCollections: null
});
}
将表单组和控件名称添加到 md-select
:
<form [formGroup]="createCardForm">
<md-select placeholder="Favorite food"
multiple="true"
formControlName="reactiveCollections">
<md-option *ngFor="let food of foods" [value]="food.value">
{{ food.viewValue }}
</md-option>
</md-select>
</form>
Plunker也更新了
export class SelectOverviewExample {
createCardForm: FormGroup;
// inject form builder
constructor(private fb: FormBuilder) {
// add collections form array to your form
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
});
}
// get method which return the formArray as control
get collections(): FormArray {
return this.createCardForm.get('collections') as FormArray;
};
// function which pushed new value to collections array
addCollectionId(val) {
// Instead of this use get property
//const collections = this.createCardForm.get('collections');
// add only once
if (!this.collections.value.includes(val)) {
this.collections.push(this.fb.control(val));
}
}
}
我也遇到了 "Property 'push' does not exist on type 'AbstractControl'" 错误,我找到了解决方案,只是删除了 const 并添加了 get 收集方法。