Angular6 form表单相关

一、form中使用的input, select等均不建议使用ngModel绑定变量,因为Angular7会移除form中的这个指令,如果在6中使用则会报警告,直接使用formControl或者formControlName绑定form即可,如下

ts文件中targetForm定义如下:

  targetForm
  constructor(private fb: FormBuilder) {
    this.targetForm = this.fb.group({
      userName: ['王XX', Validators.required],
    })
  }

提交表单的时候,可以直接从刚刚定义的targetForm中取到value值,然后对应提交

二、FormControl,FormGroup和FormArray

1、三者中FormControl属于子元素,FormGroup和FormArray可任意嵌套这三个元素
(1)FormGroup中嵌套FromControl。这是最常见的形式,上述示例中就是这种格式
(2)FormGroup中嵌套FormGroup。
这种格式一般是表单中某些项和某一项有关联关系时使用,可以通过addControl来动态添加,举个栗子:
html

{{ item }}

ts,当选择职业为teacher时

  constructor(private fb: FormBuilder){}
  this.targetForm = fb.group({
    profession: ['', Validators.required],
  })
  changeProfession(event) {
    const {value} = event
    if(value === 'teacher') {
      const fbGroup = this.fb.group({
        school: ['xxx', Validators.required],
        grade: ['', Validators.required]
      })
      // contains方法判断是否包含teacher control
      if(!this.targetForm.contains('teacher')) {
        this.targetForm.addControl('teacher', fbGroup)
      }
    } else{
      // 删除targetForm中的teacher control
      this.targetForm.removeControl('teacher')
    }
  }

(3)FormGroup中嵌套FormArray,且FormArray中嵌套FormGroup。一般用于对表单中数组的动态处理,举个栗子:
html文件

 
{{ item }}
add
delete

ts文件

 constructor(private fb: FormBuilder){
    this.targetForm = fb.group({
      profession: ['', Validators.required],
      testArr: fb.array([])
    })
  }
get testArr() {
  return this.targetForm.get('testArr') as FormArray
}
// 新增
addAction() {
    const fb = this.fb
    const fbGroup = fb.group({
        key: ['', Validators.required],
        value: ['', Validators.required],
    })
    this.targetForm.controls.testArr.push(fbGroup)
}

// 删除
removeAction(index) {
    const arr = this.targetForm.get('testArr') as FormArray
    arr.removeAt(index)
}

三、表单中常见的坑

  1. 表单中的input框回车就自动提交表单
    解决方法,在

    标签上添加onkeypress="if(event.keyCode===13||event.which===13){return false;}"

  2. 表单中的button标签,如果不设置type,点击默认触发点击事件,除了提交按钮设置type='submit',其他button需要设置type='button'属性

  3. formGroup里面嵌套formGroup,点击提交的时候外层的能触发验证,但是内层的不能触发验证。解决方法:[formGroup] = "targetForm.controls['test']"改为formGroupName="test"

  4. 谷歌浏览器中,当input type=text与type=password相邻时,input框会自动填充用户名。解决方法为:设置两个form将两个input隔离开。如下:


    

  1. formGroup中嵌套的formArray,formArray中嵌套formGroup,submit的时候,判断this.targetForm.valid时,formArray内部若不能校验,则需要查询formArray用法是否有问题,需要设置formArrayName="testArr",且子元素需要设置formGroupName = 'i',形如上栗(3);若formArray中是formControl,则子元素直接设置formControlName = 'i' 就可以了

6、开发项目时遇到一个问题,form中嵌套组件,组件中[formGroup]和父组件是同一个,通过将父组件中的formGroup传进去,从而来实时变更form。组件中属性是级联关系且必填,发现提交表单时子组件若未填写,并没有触发表单验证,通过尝试发现可通过将formGroup中的子组件的formControl调用markAsTouched()方法来出发验证。

7、动态隐藏或新增表单中的某些必填formControl有时会造成新增后修改该属性,值改了但是页面没有对应更新。我们可以不删除,隐藏时仅需设置这些属性为非必填,开放时设置为必填即可,设置代码如下

  addValidators(targetForm, attributes, validators) {
    attributes.forEach(it => {
      if (targetForm.get(it)) {
        targetForm.get(it).setValidators(validators)
      }
    })
  }

  clearValidators(targetForm, attributes) {
    attributes.forEach(it => {
      if (targetForm.get(it)) {
        targetForm.get(it).clearValidators()
        targetForm.get(it).updateValueAndValidity({onlySelf: true})
      }
    })
  }

8、表单中属性设置disabled后,通过form.value将获取不到该值,可通过form.getRawValue()获取表单值

9、切记组件中的input字段名不可和公用指令名重名,不然会同时作为指令作用在组件上,刚吃过这个亏emmm....

你可能感兴趣的:(Angular6 form表单相关)