没有 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 的目的是包含一组 FormControlFormGroup,以便您可以动态地将输入元素添加到 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 收集方法。