业务场景
使用formarray制作动态表单。每创建一个表单,页面就新增一个input显示表单填写的标题,点击编辑再跳转到点击表单的填写内容。【相关教程推荐:《angular教程》】
// 封装获取modellist get modellist() { return this.formgroup.get('modellist') as formarray } constructor(private fb: formbuilder) {} ngoninit() { // 一开始初始化arr为空数组 this.formgroup = this.fb.group({ // 内部嵌套formcontrol、formarray、formgroup modellist: this.fb.array([]) }) } // 模态框构造内部的表单 function newmodel() { return this.fb.group({ modelname: [''], // 可以继续嵌套下去,根据业务需求 }) } // 省略模态框部分代码 // 传递到模态框的formarray selectedtype: formarray
表单列表
表单详情【模态框】
由于这种模态框比较特殊,割裂了表单的formgroup之间的关系,在点击的时候需要传递参数到模态框显示部分值,如果单纯传递参数使用this.modellist.at(index)
获取实体到模态框上进行赋值修改,在模态框点击保存后会发现修改的值没有在表单更新,而表单上对input值修改发现可以影响到模态框的内容。
但是模态框新增的表单却可以响应到页面中去。
原错误代码思路
点击编辑后,将点击的formarray的元素传递给一个临时变量
this.selectedtype =
,并且对模态框表单传值。this.modellist.at(index); 模态框点击保存再将原formarray的值重新替换
this.modellist.removeat(this.modelindex) this.modellist.insert(this.modelindex, this.selectedtype)
点击新增,创建一个新的formgroup对象
保存添加push到原页面的formarray中
newmodeltype(): formgroup { return this.fb.group({ modelname: ['', validators.required], configlist: this.fb.array([]), }); } // ...省略 // 模态框显示 show() { this.isvisible = true this.selectedtype = this.newmodeltype(); } // 保存 save() { this.isvisible = false // 原页面formarray this.modellist.push(this.selectedtype); }
最后发现这种写法只能够单向改变,页面外input修改值会影响到模态框,但是模态框的值改变保存却让外部没有更新。通过console方式查看页面的formarray内部参数发现其实是有改变的,只是angular没有检测到。这个时候判断没有发生响应的原因一般是没有触发angular检测机制,仔细查看文档发现有一行很重要 angular文档在最下面写着
原本第一次阅读的时候,觉得我遵守了这种原则,因为在编辑的时候,我选择了操控原formarray进行元素删除和插入,是遵循了这种规则,但是实际上在模态框赋值就已经违反了这种原则,我在赋值的时候拿了formarray的元素实例赋值给模态框的临时变量,然后更改实例的值,又重新删除插入,本质上**作的是同一个实例,所以angular没有检测到发生变化【虽然值发生改变】
所以正确的做法是啥??
在赋值的地方不能偷懒,仍然要重新创建新对象,再拿原对象的赋值。【相当于深拷贝】
this.selectedtype = this.newmodeltype(); const old = this.modellist.at(index); this.selectedtype.setvalue({ 'modelname': old.get('modelname').value })
这时候就可以正常更新了。
总结
其实查到最后本质上还是回归文档。在排查错误也走了很多坑,而且国内基本没什么angular的文章,还得靠外网论坛去找问题。
更多编程相关知识,请访问:编程教学!!
以上就是浅析angular中怎么结合使用formarray和模态框的详细内容,更多请关注其它相关文章!