如何让Formly表单中模型的数组属性保留输入值在数组内?
解决Formly表单中数组字段绑定输入框的类型转换问题
你的核心问题是:模型中emails定义为字符串数组,但使用普通input组件绑定后,输入的字符串会直接覆盖数组,导致类型不符合预期。以下是两种可行的解决方式:
方法一:使用Formly的parser和formatter(推荐)
Formly提供了parser和formatter钩子,分别用于视图值转模型值和模型值转视图值,正好适配这种类型转换场景:
{ key: "emails", type: "input", props: { label: "Emails", required: true, }, // 将模型中的数组转为输入框显示的字符串(取第一个元素) formatter: (value: string[]) => value?.[0] || '', // 将输入框的字符串转为模型需要的数组格式 parser: (value: string) => value ? [value.trim()] : [], },
说明:
formatter:当模型值更新时,把数组的第一个元素提取出来显示在输入框中,保证输入框展示正确的内容;parser:当用户在输入框中输入内容时,将输入的字符串包装成数组,直接同步到模型和表单控件中。
方法二:使用onChanges钩子手动处理
如果更倾向于用钩子实现,可以在onChanges中判断输入值的类型,手动转换为数组:
{ key: "emails", type: "input", props: { label: "Emails", required: true, }, hooks: { onChanges: (field: FormlyFieldConfig) => { const control = field.form?.get("emails"); if (!control) return; const inputValue = control.value; // 只有当输入值是字符串时才转换,避免循环触发 if (typeof inputValue === "string") { control.setValue(inputValue.trim() ? [inputValue.trim()] : [], { emitEvent: false }); } }, }, },
说明:
- 添加
emitEvent: false是为了避免设置值后再次触发onChanges,造成循环更新; - 加入
trim()处理可以去除输入内容的首尾空格,提升数据整洁度。
以上两种方法都能实现你的预期效果:输入邮箱后,emails字段会以数组形式存储值,最终模型状态如下:
{ "name": "john", "lastName": "doe", "emails": ["john.doe@domain.com"] }
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

