Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角材质匹配列表-如何在动态FormArray上使用它?_Javascript_Angular_Typescript_Angular Material_Angular Reactive Forms - Fatal编程技术网

Javascript 角材质匹配列表-如何在动态FormArray上使用它?

Javascript 角材质匹配列表-如何在动态FormArray上使用它?,javascript,angular,typescript,angular-material,angular-reactive-forms,Javascript,Angular,Typescript,Angular Material,Angular Reactive Forms,这是我的表格(变体): 我正在使用MatChips存储字符串数组。此数组需要传递给选项: <div formArrayName="variants" *ngFor="let item of productGroup.controls['variants'].controls; let i = index;"> <div [formGroupName]="i"> <div class="row"> <mat-form-field c

这是我的表格(变体):

我正在使用
MatChips
存储字符串数组。此数组需要传递给
选项

<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>
我正在成功地将动态字段添加到我的
变体
formArray。但是,
MatChipList
对于每个动态字段都是相同的。我还需要使
MatChipList
动态化。有没有办法做到这一点?比如改变
之类的


编辑:

我不确定dom引用变量#chiplist是否是问题所在。看起来matChipList由typesOptions数组支持,但您只有一个数组。因此,每次添加matChipList组件时,它仍然与其他组件一样由同一个数组支持。你需要有一个typesOptions数组,一个数组数组。然后,在添加项时,还将一个新的子数组推送到typesOptions(类似地,删除removeItem的子数组)

我还没有把它编出来,只是看了一下代码后的一个建议

编辑-根据James的stackblitz编写解决方案

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

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

尝试将formGroup设为新组件,并向其输入formGroup(而不是formGroupName)


this.typesOptions.push(value.trim());this.typesOptionsArray.push(this.typesOptions)如何使用这个数组来阻止重复的值?James如果你提出一个工作的StackBlitz来说明这个问题,你应该很快得到一个工作的答案。也许举一个有角度的例子,这是最干净的方法。非常感谢。
// 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);
    }
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);
    }
  }
}
<div formArrayName="variants" *ngFor="let item of productGroup.controls['variants'].controls; let i = index;">
  <variant [varientGroup]="item"><varient>
  <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>
<div [formGroup]="varientGroup">
 <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"
              [matChipInputFor]="chipList"
              [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
              [matChipInputAddOnBlur]="true"
              (matChipInputTokenEnd)="addOpt($event)">
      </mat-chip-list>
    </mat-form-field>
  </div>
</div>
@Input()varientGroup: FormGroup