Angular: 深度复制反应形式

Angular: Deep copy a reactive form

我需要对反应式表单进行深度复制。 我尝试使用 ES6 扩展语法来克隆表单。我使用 Typescript 泛型将扩展语法的 return 值强制转换为 FormGroup。此外,克隆表单变量的类型设置为 FormGroup.

但是当通过这种方式克隆表单时,克隆的表单变量上的类型丢失了,即它不再是FormGroup的类型。所以,克隆的表格不可用。

这是相同的堆栈闪电战:form cloning

以上克隆方式有什么问题?为什么类型 FormGroup 在克隆的表单中丢失?

您可以使用 Objectassign() 方法,语法如下:

Object.assign(target, ...sources)

对于你的情况,你可以这样做:

this.myForm2 = Object.assign({}, this.myForm)

那么,Object.assign() 是做什么的?

This method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

详情请看here

希望对您有所帮助。

只需使用 return 一个 FormGroup 的函数。您可以使用 setValue 或 patchValue 来提供相同的值。有些人喜欢(我直接使用 FormGroup 的构造函数,但你也可以使用 FormBuilder)

  createForm(data:any)
  {
    data=data || {name:null,group:{prop1:null,prop2:null}}
    return new FormGroup({
      name: new FormControl(data.name),
      group:new FormGroup({
        prop1:new FormControl(data.group.prop1),
        prop2:new FormControl(data.group.prop2)
      })
    })
  }

/*you can also
  createForm(data:any)
  {
    const form=new FormGroup({
      name: new FormControl(),
      group:new FormGroup({
        prop1:new FormControl(),
        prop2:new FormControl()
      })
    })
    if (data)
      form.patchValue(data)

    return form
  }
  */

在 ngOnInit 中,例如

  ngOnInit() {
       this.myForm=this.createForm({name:"name",group:{prop1:"prop1",prop2:"prop2"}});
       this.myForm2=this.createForm(null);
       this.myForm2.patchValue(this.myForm.value)
       //or this.myForm2.setValue(this.myForm.value)
  }

link

Lodash 可以很好地深度克隆 FormGroup,即使它们是嵌套的。如果您正在处理动态表单,手动重新创建表单可能会导致大量代码行(例如检查是否存在条件 forms/controls)。鉴于这种情况,在大多数情况下,我们可以通过导入 say * as _ from 'lodash' 并使用 .cloneDeep. 克隆 FormGroup、FormArray 或 FormControl 来解决它,例如:

const clonedForm = _.cloneDeep(this.myForm);

然后您将能够像使用 myForm 一样使用 clonedForm 及其内部控件,而无需修改 myForm 的嵌套控件。

这是我的解决方案:

app.component.ts

export class AppComponent {
  formulario = new Formulario();
}

export class Formulario {
  getFormulario() {
    return {
      nombre: new FormControl('', [Validators.required]),
      email: new FormControl('', [Validators.required, Validators.email]),
      password: new FormControl(''),
      cod_perfil: new FormControl('', [Validators.required]),
      validoHasta: new FormControl('')
    };
  }
}

app.component.html

<child [formularios]="formulario"></child>

现在您可以在这里和任何地方获得您的表单的不同实例,

child.component.ts

export class ChildComponent implements OnInit {
  @Input() formularios: any;
  @Output() formulariosIdiomas = new EventEmitter<any>();
  langs = ['es', 'en'];    

  ngOnInit() {
    console.log(this.formularios.getFormulario());

    // Different instances
    this.langs.forEach(lang => {
      this.formulariosIdiomas[lang] = new FormGroup(
        this.formularios.getFormulario()
      );
    });

  }
}