FormArray没有FormControls,只是字符串Angular 2

时间:2017-09-11 19:26:46

标签: angular angular-forms

我的后端有两个字符串数组,我必须用一个字符串或多个字符串填充。但它们不是关键值对。我试图将一个字符串推入其中一个数组,但遇到的事实是我没有,并且无法指定一个控件:值对。

我的formArray看起来像

collections: new FormArray([]),

我的html选择字符串

              <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);

}

我收到错误'类型'字符串的参数'不能分配给'AbstractControl'类型的参数。

因为我无法推送一个控件:值对而只有字符串/字符串如何在保持整体形式的同时将字符串推送到数组?

非常感谢任何帮助/提示/建议。

3 个答案:

答案 0 :(得分:7)

您可以使用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来自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也会更新

答案 1 :(得分:2)

FormArray的目的是包含一组FormControlFormGroup,以便您可以动态地将输入元素添加到HTML表单中。我不认为这是你打算做的,一个正常的数组可能适合你的目的。

这是来自文档:

  

跟踪FormControl数组的值和有效性状态,   FormGroup或FormArray实例。 FormArray聚合的值   每个子FormControl成一个数组。它通过计算其状态   减少其子女的身份。

     

例如,如果其中之一   FormArray中的控件无效,整个数组变为无效。   FormArray是用于的三个基本构建块之一   在Angular中定义表单,以及FormControl和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

有意义吗?

答案 2 :(得分:0)

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));
    }
  }
}

   我还收到“类型'AbstractControl'上不存在属性'push'”错误,并且仅通过删除const并添加了用于收集的get方法,我找到了解决方案。