动态添加多个表单控件

时间:2019-06-25 09:55:17

标签: javascript html angular

我有一个组件,可以基于模板对象创建带有“添加其他字段”和“删除此字段”选项的表单控件。

例如,此模板:

assignmentLinkTemplateObj = {
    name: 'Name',
    url: 'URL'
}

应创建2个文本字段,字段名称分别为“ name”和“ url”,以及占位符“ Name”和“ URL”。现在,该组件将这些字段添加到“添加另一个任务”的单击上。然后点击“删除此任务”,删除这两个字段的组合。

类似地,如果模板为:

pastTopicalLinkTemplateObj = {
    name: 'Name',
    type: ['ER', 'MS', 'GT', 'QP'],
    url: 'URL'
}

该类型是一个数组,因此组件将呈现一个下拉列表,其中填充了该数组的值。

这就是我所做的:

标记:

<form nz-form [formGroup]="validateForm">
  <nz-form-item *ngFor="let control of controlArray; let i = index">
    <nz-form-label [nzXs]="24" [nzSm]="6" *ngIf="i == 0" [nzFor]="control[field]">
        <!-- RENDER DROPDOWNS OR TEXT FIELDS -->
        <ng-container *ngFor="let field of objectKeys(fieldsTemplate)">
            <nz-select *ngFor="let option of fieldsTemplate[field]" *ngIf="isObj(fieldsTemplate[field])">
                <nz-option [nzLabel]="option" [nzValue]="option"></nz-option>
            </nz-select>
            <input 
                *ngIf="!isObj(fieldsTemplate[field])"
                nz-input
                style="margin-right:8px;"
                [placeholder]="fieldsTemplate[field]"
                [attr.id]="control.id"
                [formControlName]="control['id']+control[field]"
            />
        </ng-container>

        <!-- REMOVE FIELD -->
        <i nz-icon type="minus-circle-o" class="dynamic-delete-button" (click)="removeField(control['id'], $event)"></i>
      </div>
    </nz-form-control>
  </nz-form-item>
  <nz-form-item>
    <nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 20, offset: 6 }">
        <!-- ADD ANOTHER FIELD -->
        <button nz-button nzType="dashed" style="width:inherit;" (click)="addField($event)">
            <i nz-icon type="plus"></i> Add
        </button>
    </nz-form-control>
  </nz-form-item>
</form>

Component.ts:

validateForm: FormGroup;

@Input('name') name;
@Input('fieldsTemplate') fieldsTemplate;
@Input('error_text') error_text;

@Input('controlArray') controlArray: any = [];

@Output('valueAdd') valueAdd = new EventEmitter();
@Output('valueRemove') valueRemove = new EventEmitter();

objectKeys = Object.keys;

keys;

isObj(obj) {
  return typeof obj == 'object';
}

addField(e ? : MouseEvent): void {
  if (e) {
    e.preventDefault();
  }
  const id = this.controlArray.length > 0 ? this.controlArray[this.controlArray.length - 1].id + 1 : 0;

  this.keys = Object.keys(this.fieldsTemplate);

  const control = {
    id
  };

  this.keys.forEach(key => {
    control[key] = key;
  });

  const index = this.controlArray.push(control);

  this.keys.forEach(key => {
    this.validateForm.addControl(
      `${id}${this.controlArray[index - 1][key]}`,
      new FormControl(null, Validators.required)
    );
  })

  this.valueAdd.emit(this.controlArray);
}

removeField(id, e: MouseEvent): void {
  e.preventDefault();
  if (this.controlArray.length > 1) {
    const index = this.getControlById(id);
    this.controlArray.splice(index, 1);
    this.keys.forEach(key => {
      this.validateForm.removeControl(`${id}${this.controlArray[index - 1][key]}`);
    });
    this.valueRemove.emit(this.controlArray[index]);
  }
}

getControlById(id) {
  let index;
  this.controlArray.filter((control, i) => {
    if (control.id === id) {
      index = i;
    }
  });
  return index;
}

getFormControl(id: string): AbstractControl {
  return this.validateForm.controls[this.getControlById(id)];
}

constructor(private fb: FormBuilder) {}

ngOnInit(): void {
  this.validateForm = new FormGroup({

  });
}

问题: this.validateForm.value现在给我一个类似这样的对象:

{0name: "asd", 0url: "asd", 1name: "asd1", 1url: "asd2"}

有没有其他方法可以将表单控件映射到对象数组,以便每个字段组合都是一个对象,而整个表单是这些对象的数组。

0 个答案:

没有答案