Angular 2 - 如何清理表单中的数组

时间:2017-10-19 08:33:51

标签: arrays forms angular angular2-forms

我需要帮助。 我在Angular2(4)中创建了应用程序,我在其中有2个选择框和1个复选框。而我想要实现对这个盒子的依赖。例如,我有这个数组:

dataJSON = [
    {
      productName: 'Product 1',
      variants: [
        {
          variantName: 'Variant1',
          variantType: [
            'Type1', 'Type2', 'Type3'
          ]
        },
        {
          variantName: 'Variant2',
          variantType: [
            'Type1', 'Type2', 'Type3'
          ]
        },
        {
          variantName: 'Variant3',
          variantType: [
            'Type1', 'Type2', 'Type3'
          ]
        },
      ]
    },
    {
      productName: 'Product 2',
      variants: [
        {
          variantName: 'Variant1',
          variantType: [
            'Type1', 'Type2', 'Type3', 'Type4'
          ]
        },
        {
          variantName: 'Variant2',
          variantType: [
            'Type1', 'Type2', 'Type3'
          ]
        }
      ]
    },
    {
      productName: 'Product 3',
      variants: [
        {
          variantName: 'Variant1',
          variantType: [
            'Type1', 'Type2', 'Type3'
          ]
        },
        {
          variantName: 'Variant2',
          variantType: [
            'Type1', 'Type2', 'Type3'
          ]
        },
        {
          variantName: 'Variant3',
          variantType: [
            'Type1', 'Type2', 'Type3'
          ]
        },
        {
          variantName: 'Variant4',
          variantType: [
            'Type1', 'Type2', 'Type3', 'Type4'
          ]
        }
      ]
    }
  ];

因此,当我在第一个选择框中选择'产品1'然后在第二个选择框中,我将有选项:' Variant1',' Variant2',' Variant3'。然后当我选择' Variant1'我将有复选框选项:' Type1',' Type2',' Type3'。 当我选择everithing时,我想保存什么,并根据API请求数据。

我现在拥有的。

<form [formGroup]="productForm" (ngSubmit)="submitForm()">

    <div class="form-group row">
      <div class="col-md-4 col-sm-4 col-lg-4">
        <label>Product</label>
        <select formControlName="productName" (change)="productChanged()" class="form-control">
          <option >Pick a Product...</option>
          <option *ngFor="let l of dataJSON">{{l.productName}}</option>
        </select>
      </div>
        <label>Variant</label>
      <div class="col-md-4 col-sm-4 col-lg-4">
        <select formControlName="variants" (change)="variantsChanged()" class="form-control">
          <ng-template  ngFor let-variant [ngForOf]="(variantAfterChangeEvent)">
          <option>Pick a variant...</option>
            <option *ngFor="let v of variant.variants">{{v.variantName}}</option>
          </ng-template>
        </select>
      </div>
      <div class="col-md-4 col-sm-4 col-lg-4">
        <label>Type</label>
        <ng-template  ngFor let-type [ngForOf]="(typeAfterChangeEvent)">
          <div *ngFor="let t of type[0].variantType">
            <input type="checkbox" class="minimal" (change)="onChange(t, $event.target.checked)"> {{t}} 
          </div>
        </ng-template>            
      </div>
    </div>

     <button type="submit" class="btn btn-primary">Submit</button>
 </form>

variantAfterChangeEvent: any[];
typeAfterChangeEvent: any[];
productForm: any;


constructor(private fb: FormBuilder) {
    this.productForm = fb.group({
        productName: [],
        variants: [],
        type: this.fb.array([])
    });
}

productChanged() {
    const productName = this.productForm.get('productName').value;
    this.variantAfterChangeEvent = this.dataJSON.filter(s = > s.productName);
}

variantsChanged() {
    const variants = this.productForm.get('variants').value;

    this.typeAfterChangeEvent = this.variantAfterChangeEvent
      .filter((element) =>
        element.variants.some((subElement) => subElement.variantName === variants))
      .map(element => {
        const newElt = Object.assign({}, element ); // copies element
        return newElt.variants.filter(subElement => subElement.variantName === variants);
    });
}

onChange(type: string, isChecked: boolean) {
    const typeFromArray = <FormArray>this.productForm.controls.type;

    if (isChecked) {
      typeFromArray.push(new FormControl(type));
    } else {
      const index = typeFromArray.controls.findIndex(x => x.value === type)
      typeFromArray.removeAt(index);
    }

    console.log('onChange() ' + JSON.stringify(this.productForm.value));
 }

 submitForm() {
    console.log('submitForm ' + JSON.stringify(this.productForm.value));
 }

但是现在我选择产品 - &gt;变体 - &gt;类型和比之前提交我想要更改产品并选择其他不同的产品 - &gt;变体 - &gt;输入然后提交我得到我选择的最后一个但是在&#39;键入&#39;我也是第一次选择的。那么我该如何清理&#39;键入&#39;当我在Form = Product或Variant中更改somenting时,productForm中的数组。 如果没有选择所有项目(框),我怎么能禁用提交表格按钮?

编辑: Plnkr

1 个答案:

答案 0 :(得分:0)

如果你能创造一个plunker会更好。  根据我的理解,您可以从每个控件中获取ngModel,并在更改时清除其他控件的值。

要在选中所有值之前禁用表单,请在每个控件中添加required属性,并在提交按钮中添加[disabled]="!productForm.valid"