Angular6 form表单相关

作者: 桃之_夭夭_ | 来源:发表于2018-07-12 16:16 被阅读327次

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

    <form [formGroup]="targetForm" (ngSubmit)="save()" onkeypress="if(event.keyCode==13||event.which==13){return false;}">
      <div>
        <label>
          姓名
        </label>
        <mat-form-field [floatLabel]="'never'">
          <input matInput autocomplete="username" disableautocomplete type="text" name="username" formControlName="username" required>
        </mat-form-field>
      </div>
      <div>
        <button mat-button type="submit" class="sure">保存</button>
      </div>
    </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

    <form [formGroup]="targetForm" (ngSubmit)="save()" onkeypress="if(event.keyCode==13||event.which==13){return false;}">
      <div>
        <label>
          职业
        </label>
        <mat-form-field [floatLabel]="'never'" class="dialog-input">
          <mat-select placeholder="请选择" formControlName="profession"
                      (selectionChange)="changeProfession($event)" required>
            <mat-option *ngFor="let item of professions" [value]="item">
              {{ item }}
            </mat-option>
          </mat-select>
        </mat-form-field>
      </div>
      <div *ngIf="targetForm.get('profession').value === 'teacher'" formGroupName="teacher">
        <div>
          <label>
            学校
          </label>
          <mat-form-field [floatLabel]="'never'">
            <input matInput autocomplete="school" disableautocomplete type="text" name="school" formControlName="school" required>
          </mat-form-field>
        </div>
        <div>
          <label>
            年级
          </label>
          <mat-form-field [floatLabel]="'never'">
            <input matInput autocomplete="grade" disableautocomplete type="text" name="grade" formControlName="grade" required>
          </mat-form-field>
        </div>
      </div>
      <div>
        <button mat-button type="submit" class="sure">保存</button>
      </div>
    </form>
    

    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文件

     <div>
        <label>
          职业
        </label>
        <mat-form-field [floatLabel]="'never'" class="dialog-input">
              <mat-select placeholder="请选择" formControlName="profession" 
    (selectionChange)="changeProfession($event)" required>
                <mat-option *ngFor="let item of professions" [value]="item">
                  {{ item }}
                </mat-option>
              </mat-select>
          </mat-form-field>
      </div>
      <ng-container  *ngIf="targetForm.get('profession').value === 'teacher'">
      <mat-icon style="color: #3CB371" (click)="addAction()">add</mat-icon>
    <div formArrayName="testArr">
      <ng-container *ngFor="let test of testArr.controls;let index = index" [formGroupName]="i">
        <div class="col-5">
          <mat-form-field class="w-100">
            <mat-form-field class="w-100">
              <input autocomplete="off" disableautocomplete matInput type="text" formControlName="key" placeholder="key">
            </mat-form-field>
          </mat-form-field>
        </div>
        <div class="col-5">
          <mat-form-field class="w-100">
            <input autocomplete="off" disableautocomplete matInput type="text" formControlName="value" placeholder="value">
          </mat-form-field>
        </div>
        <div class="m-auto text-right">
          <mat-icon style="color: #3CB371" class="cancelMatIcon" (click)="removeAction(index)">
            delete
          </mat-icon>
        </div>
      </ng-container >
    </div>
    </ng-container>
    

    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框回车就自动提交表单
      解决方法,在<form>标签上添加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隔离开。如下:

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

    相关文章

      网友评论

        本文标题:Angular6 form表单相关

        本文链接:https://www.haomeiwen.com/subject/hrqpuftx.html