Angular: 深度复制反应形式
Angular: Deep copy a reactive form
我需要对反应式表单进行深度复制。
我尝试使用 ES6 扩展语法来克隆表单。我使用 Typescript 泛型将扩展语法的 return 值强制转换为 FormGroup
。此外,克隆表单变量的类型设置为 FormGroup
.
但是当通过这种方式克隆表单时,克隆的表单变量上的类型丢失了,即它不再是FormGroup
的类型。所以,克隆的表格不可用。
这是相同的堆栈闪电战:form cloning
以上克隆方式有什么问题?为什么类型 FormGroup
在克隆的表单中丢失?
您可以使用 Object
的 assign()
方法,语法如下:
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)
}
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()
);
});
}
}
我需要对反应式表单进行深度复制。
我尝试使用 ES6 扩展语法来克隆表单。我使用 Typescript 泛型将扩展语法的 return 值强制转换为 FormGroup
。此外,克隆表单变量的类型设置为 FormGroup
.
但是当通过这种方式克隆表单时,克隆的表单变量上的类型丢失了,即它不再是FormGroup
的类型。所以,克隆的表格不可用。
这是相同的堆栈闪电战:form cloning
以上克隆方式有什么问题?为什么类型 FormGroup
在克隆的表单中丢失?
您可以使用 Object
的 assign()
方法,语法如下:
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)
}
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()
);
});
}
}