角材料MatChipList-如何在动态FormArray上使用它? [英] Angular Material MatChipList - how to use it on a Dynamic FormArray?

查看:77
本文介绍了角材料MatChipList-如何在动态FormArray上使用它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

StackBlitz

这是我的FormArray(变体):

Here is my FormArray (variants):

this.productGroup = this.fb.group({
    name: '',
    variants: this.fb.array([
      this.fb.group({
        type: '',
        options: ''
      })
    ])
})

我正在使用MatChips存储字符串数组.该数组需要传递给options:

I'm using MatChips to store a string array. This array needs to be passed to options:

<div formArrayName="variants" *ngFor="let item of productGroup.controls['variants'].controls; let i = index;">
  <div [formGroupName]="i">
    <div class="row">
      <mat-form-field class="col-12">
        <input formControlName="type">
      </mat-form-field>
    </div>
    <div class="row">
      <mat-form-field class="col-12">
        <mat-chip-list #chipList>
          <mat-chip *ngFor="let opt of typesOptions" [selectable]="true"
                    [removable]="true" (removed)="removeOpt(opt)">
            {{opt}}
            <mat-icon matChipRemove>cancel</mat-icon>
          </mat-chip>
          <input placeholder="Conjunto de opções deste Tipo"
                  formControlName="options"
                  [matChipInputFor]="chipList"
                  [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
                  [matChipInputAddOnBlur]="true"
                  (matChipInputTokenEnd)="addOpt($event)">
        </mat-chip-list>
      </mat-form-field>
    </div>
  </div>
  <div class="row">
    <a href="javascript:" (click)="addItem()"> Add Variants </a>
    <a href="javascript:" (click)="removeItem(i)" *ngIf="i > 0"> Remove Variants </a>
  </div>
</div>

以下是方法:

// Dynamic Methods
  addItem(): void {
    this.variantsArray = this.productGroup.get('variants') as FormArray;
    this.variantsArray.push(this.fb.group({
      type: '',
      options: ''
    }));
  }
  removeItem(index: number) {
    this.variantsArray.removeAt(index);
  }

// MatChip Methods
  addOpt(item: number, event: MatChipInputEvent): void {
    const input = event.input;
    const value = event.value;
    // Add our fruit
    if ((value || '').trim()) {
      this.typesOptions.push(value.trim());
    }
    // Reset the input value
    if (input) {
      input.value = '';
    }
  }
  removeOpt(opt: string): void {
    const index = this.typesOptions.indexOf(opt);
    if (index >= 0) {
      this.typesOptions.splice(index, 1);
    }

我已成功将动态字段添加到我的variants formArray中.但是对于每个动态字段,MatChipList都是相同的.我还需要使MatChipList动态.有没有办法做到这一点?就像更改<mat-chip-list #chipList+i>之类的.

I'm successfully adding dynamic fields to my variants formArray. However MatChipList is the same for every dynamic field. I need to make MatChipList dynamic as well. Is there a way to achieve this? Like changing <mat-chip-list #chipList+i> or something like that.

StackBlitz

推荐答案

我不确定dom参考变量#chiplist是问题所在.看起来matChipList由typesOptions数组支持,但是您只有一个数组.因此,每次添加matChipList组件时,它都仍由与所有其他数组相同的数组支持.您需要具有一个typesOptions数组,一个数组数组.然后,当您添加addItem时,还可以将一个新的子数组推入typesOptions中(并类似地为removeItem删除一个子数组).

I'm not sure the dom reference variable #chiplist is the issue. It looks like the matChipList is backed by the typesOptions array, but you only have one array. So every time you add a matChipList component it is still being backed by the same array as all the others. You need to have an array of typesOptions, an array of arrays. Then when you addItem, you also push a new sub array to typesOptions (and similarly remove one for removeItem).

我还没有编写代码,只是看代码的建议.

I haven't coded this up, just a suggestion from looking at the code.

编辑-基于James的堆栈闪电编码了一个解决方案.

Edit - coded up a solution based on James's stackblitz.

https://stackblitz.com/edit/angular-3od6rd-jkidxf

请注意,我没有详细研究delete变体如何组合在一起,理想情况下,我可能想使用一个键/值对,以dom输入元素id作为键来跟踪变体选项(在MatChipInputEvent),而不是依赖于外部循环索引.

Note I haven't looked in detail at how the delete variant holds together, ideally I'd probably like to use a key/value pair to track the variant options using the dom input element id as the key (which is in the MatChipInputEvent), instead of relying on the outer loop index.

一些来自闪电战的代码:

Some code from the stackblitz:

export class ChipsOverviewExample {
  productGroup: FormGroup;
  variantsArray: FormArray;
  typesOptionsArray: string[][] = [];
  readonly separatorKeysCodes: number[] = [ENTER, COMMA];

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.productGroup = this.fb.group({
      name: '',
      variants: this.fb.array([
        this.fb.group({
          type: '',
          options: ''
        })
      ]),
    });
    this.typesOptionsArray.push([]);
  }

  saveProduct(form: FormGroup) {
    console.log(form);
  }

  // Add new item to FormArray
  addItem(): void {
    this.variantsArray = this.productGroup.get('variants') as FormArray;
    this.variantsArray.push(this.fb.group({
      type: '',
      options: ''
    }));

    this.typesOptionsArray.push([]);
  }

  removeItem(index: number) {
    this.variantsArray.removeAt(index);
  }

  addOpt(event: MatChipInputEvent, index: number): void {
    const input = event.input;
    const value = event.value;
    // Add our fruit
    if ((value || '').trim()) {
      this.typesOptionsArray[index].push(value.trim());

    }
    // Reset the input value
    if (input) {
      input.value = '';
    }
  }

  removeOpt(opt: string, index: number): void {
    const optIndex = this.typesOptionsArray[index].indexOf(opt);
    if (optIndex >= 0) {
      this.typesOptionsArray[index].splice(optIndex, 1);
    }
  }
}

这篇关于角材料MatChipList-如何在动态FormArray上使用它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆