Angular 4中动态添加控件

时间:2018-11-23 22:40:30

标签: angular

在此示例中,我创建了一个小表单,可以在其中单击“添加预阶段”按钮来添加动态控件。

在添加了几个预阶段之后,我将选择阶段类型,如果选择的值为EMS,则仅应为该行添加一个额外的控件(phaseType1),而其他行则不应更改

我使用以下逻辑,但不起作用。您能帮我提出您的建议/指标吗?

app.component.ts代码片段:

import { Component, OnInit, Input } from '@angular/core';
import { FormBuilder, FormArray, FormGroup, AbstractControl } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  phaseForm: FormGroup; 
  selectedValue: string;
  emsSelected: boolean = false;

  constructor(private _fb: FormBuilder){}

  ngOnInit(){
    console.log("In ngonit");
    this.phaseForm = this._fb.group({
      userName: [''],
      phaseExecutions: this._fb.group({
        PRE: this._fb.array([this.addPhase()])
      }) 
    });   
    this.selectedValue=""; 
  }

  addPhase(){
    console.log(22);
    return this._fb.group({
      phaseType: [''],
      phaseValue: [''],
      phaseValue1: ['']
    });
  }

  get phaseArray(){     
    const control = <FormArray>(<FormGroup>this.phaseForm.get('phaseExecutions')).get('PRE');    
    return control;
  }

  addMorePhase(){   
    this.phaseArray.push(this.addPhase());
  } 

  onChange(val,index: number){
    console.log("emsSelected Value is "+this.emsSelected);
    if (val === 'EMS'){
      console.log("EMS");
      this.emsSelected=true;
      this.phaseArray.at(index).patchValue({
      phaseType: ['EMS'],
      phaseValue: [''],
      phaseValue1: ['']
      })
    } else {
      this.emsSelected=false;
    }

    console.log("selected value is "+val +" and index is " + index);
  }

  onSubmit(){
    console.log(this.phaseForm.value);
  }
}

app.component.html的代码段:

<form [formGroup]="phaseForm" class="xx" novalidate (ngSubmit)="onSubmit()">
  <div class="row">
    <label class="col-sm-1">Username:</label>
    <input formControlName="userName" type="text" class="form-control col-sm-3">
  </div>
  <div formGroupName="phaseExecutions">
    <h2>Add the phases</h2>
    PRE Phase:
    <button type="button" class="btn btn-secondary btn-sm" (click)="addMorePhase()">Add Pre-Phase</button>
    <div formArrayName="PRE">
      <div *ngFor="let phase of phaseArray.controls; let i = index;" [formGroupName]="i">
        <div class="row">
          <label class="col-sm-2">Phase type:</label>
          <label class="col-sm-1"></label>
          <label class="col-sm-2">Phase value:</label>
          <div *ngIf="emsSelected">
            <label class="col-sm-1"></label>
            <label class="col-sm-2">Phase value1:</label>
          </div>
        </div>
        <div class="row">
          <select class="form-control col-sm-2" formControlName="phaseType" (change)="onChange($event.target.value,i)">
            <option value=""></option>
            <option value="EMS">EMS</option>
            <option value="SQL">SQL</option>
            <option value="Linux">Linux</option>
          </select>
          <label class="col-sm-1"></label>
          <input type="text" class="form-control col-sm-2" formControlName="phaseValue">
          <div *ngIf="emsSelected">
            <label class="col-sm-1"></label>
            <input type="text" class="form-control col-sm-2" formControlName="phaseValue1">
          </div>
        </div>
      </div>
    </div>
  </div>
  <br>

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

1 个答案:

答案 0 :(得分:0)

您可以在addControl()实例上使用类似removeControl()FormGroup的方法。

在这种情况下,您的onChange方法将是这样:

onChange(val, index: number) {
  if (val === 'EMS') {
    (<FormGroup>this.phaseArray.at(index))
      .addControl('phaseValue1', this._fb.control([]));
  } else {
    (<FormGroup>this.phaseArray.at(index))
      .removeControl('phaseValue1');
  }
}

默认情况下,您还必须删除要添加到phaseValue1的{​​{1}}字段,因为现在将根据该特定组的select字段的值来动态添加或删除该字段。

FormGroup

最后,在模板中,您可以代替使用addPhase() { return this._fb.group({ phaseType: [''], phaseValue: [''] }); } ,而必须创建一个方法,该方法告诉特定索引处*ngIf="emsSelected"中的FormGroup是否具有{ FormArray代表FormControl。为此,您可以在组件类中定义一个方法:

phaseValue1

然后在模板中使用它:

hasPhaseValue1At(index) {
  return (<FormGroup>this.phaseArray.at(index))
    .get('phaseValue1') ? true : false;
}

这是您推荐的Sample StackBlitz