美文网首页
模板式表单校验和 表单处理实战

模板式表单校验和 表单处理实战

作者: 2764906e4d3d | 来源:发表于2019-01-31 21:06 被阅读0次

    模板式表单校验

    1. 在模板式表单中后台没有像响应式的数据模型,指令是唯一能使用的东西,需要将校验器方法包装成指令,然后在模板中使用
    2. 在模板式表单中还可以使用angular默认已经定义的校验器required和minlength等,但是为了避免和HTML中的属性发生冲突可以使用novalidate来关闭浏览器默认的表单校验
    <form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)" novalidate>
    
      <div>手机号:<input ngModel required name="mobile" type="number"></div>
    
      <button type="submit">注册</button>
    </form>
    
    1. 使用ng命令生成一个指令

    ng g directive directives/mobileValidator

    1. 指令 就是一个没有模板的组件,组件作为标签来使用,指令可以作为HTML的属性来使用
    2. 将之前写的校验方法包装到指令中去,在装饰器中写一个providers提供器,校验器的包装指令的token是固定的NG_VALIDATORS
    3. 将校验手机号的方法包装成指令
    import { Directive } from '@angular/core';
    import {NG_VALIDATORS} from '@angular/forms';
    import {mobileValidator} from '../validator/validators';
    
    @Directive({
      selector: '[mobile]',
      providers:[{provide:NG_VALIDATORS, useValue:mobileValidator ,multi:true}]
    })
    export class MobileValidatorDirective {
    
      constructor() { }
    
    }
    
    <form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)" novalidate>
      <div>用户名:<input ngModel required minlength="6" name="username" type="text"></div>
      <div>手机号:<input ngModel  mobile name="mobile" type="number"></div>
    <div ngModelGroup="passwordsGroup" equal>
      <div>密码:<input ngModel minlength="6" name="password" type="password"></div>
      <div>确认密码:<input ngModel name="pconfirm" type="password"></div>
    </div>
      <button type="submit">注册</button>
    </form>
    
    1. 模板式表单中由于组件里没有可以编程控制的数据模型,所以如果想要在了解表单中的任何信息,都要从模板式将信息传给组件控制器,在提交表单时,为了得知表单是否有效只能在onSubmit方法中传入
    <form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value,myForm.valid)" novalidate>
       <button type="submit">注册</button>
    </form>
    
    onSubmit(value:any,valid:boolean){
      console.log(valid);
      console.log(value);
    }
    
    1. 与响应式表单相同使用hasError方法显示错误信息,但是由于模板式表单并没有formModel属性,所以使用myForm.form来调用hasError方法,
    <form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value,myForm.valid)" novalidate>
      <div>用户名:<input ngModel required minlength="6" name="username" type="text"></div>
      <div [hidden]="myForm.form.get('username').valid || formModel.get('username').untouched">
        <div [hidden]="!myForm.form.hasError('required','username')">
          用户名是必填项
        </div>
        <div [hidden]="!myForm.form.hasError('minlength','username')">
          用户最小长度为6
        </div>
      </div>
      <div>手机号:<input ngModel  mobile name="mobile" type="number"></div>
      <div [hidden]="!myForm.form.hasError('mobile','mobile')||formModel.get('mobile').untouched">
        请输入正确的mobile
      </div>
    <div ngModelGroup="passwordsGroup" equal>
      <div>密码:<input ngModel minlength="6" name="password" type="password"></div>
      <div [hidden]="!myForm.form.hasError('minlength',['passwordsGroup','password'])">
        密码最小长度为6
      </div>
      <div>确认密码:<input ngModel name="pconfirm" type="password"></div>
    </div>
      <div [hidden]="!myForm.form.hasError('equal','passwordsGroup')">
        {{myForm.form.getError('equal','passwordsGroup')?.descxx}}
      </div>
      <button type="submit">注册</button>
    </form>
    
    1. 通过状态属性来决定是否显示,但是不能这样myForm.form.get('username').valid||formModel.get('username').untouched直接获取状态属性值
    2. 模板式表单和响应式表单不同,它的模型的值和状态的变更是异步的,而且很难控制,如果使用同步的方式去访问这些属性就会报错,如果在模板式表单中访问这些属性,使用input属性绑定
    <form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value,myForm.valid)" novalidate>
      <div>用户名:<input ngModel required minlength="6" name="username" (input)="onMobileInput(myForm)" type="text"></div>
      <div [hidden]="mobileValid||mobileUntouched">
        <div [hidden]="!myForm.form.hasError('required','username')">
          用户名是必填项
        </div>
        <div [hidden]="!myForm.form.hasError('minlength','username')">
          用户最小长度为6
        </div>
      </div>
      </div>
      <button type="submit">注册</button>
    </form>
    
    mobileValid:boolean=true;
    mobileUntouched=true;
    
    onMobileInput(form: NgForm) {
      if(form){
        this.mobileValid=form.form.get("mobile").valid;
        this.mobileUntouched=form.form.get("mobile").untouched;
      }
    }
    

    表单处理实战

    1. 需要实现的功能
      处理商品搜索表单
      在商品名称中输入时,提示最少输入三个字
      在商品价格中输入负数时,提示商品价格不能为负数
      商品类别中展示所以的商品类别
      点击搜索时,如果表单中有字段不合法时,控制中不打印任何数据
    2. 往productService添加一个新的方法来获取所有可用商品类别
    getAllCategories():string[]{
      return ["电子产品","硬件设备","图书"];
    }
    
    1. 使用响应式表单完成效果
    export class SearchComponent implements OnInit {
    
    
      formModel: FormGroup;
    
      categories: string[];
    
      constructor(private productService:ProductService) {
        let fb=new FormBuilder();
        this.formModel=fb.group({
          title:['',Validators.minLength(3)],
          price:[null,this.positiveNumberValidator],
          category:['-1']
        })
    
      }
    
      ngOnInit() {
        this.categories=this.productService.getAllCategories();
      }
    
      positiveNumberValidator(control: FormControl): any {
        let value = control.value;
        if (!value) {
          return null;
        }
        let price = parseInt(value);
    
        if (price > 0) {
          return null;
        } else {
          return { positiveNumber: true }
        }
      }
    
      onSubmit(): void {
        if (this.formModel.valid) {
          console.log(this.formModel.value)
        }
      }
    
    }
     }
    
    1. 建立一个表单的数据模型,将数据模型和模板HTML元素连接起来
    <form [formGroup]="formModel" (ngSubmit) = "onSubmit()" novalidate>
      <div class="form-group" [class.has-error]="formModel.hasError('minlength','title')">
        <label for="productTitle">商品名称:</label>
        <input type="text" formControlName="title" id="productTitle"  class="form-control" placeholder="商品名称">
        <span class="help-block" [class.hidden]="!formModel.hasError('minlength','title')">请至少输入三个字符</span>
      </div>
      <div class="form-group" [class.has-error]="formModel.hasError('positiveNumber','price')">
        <label for="productPrice">商品价格:</label>
        <input type="text" formControlName="price" id="productPrice" name="productPrice" class="form-control" placeholder="商品价格">
        <span class="help-block" [class.hidden]="!formModel.hasError('positiveNumber','price')">请输入正数</span>
      </div>
      <div class="form-group">
        <label for="productCategory">商品类别:</label>
        <select formControlName="category" class="form-control" id="productCategory">
          <option value="-1">--全部分类--</option>
          <option  *ngFor="let category of categories" [value]="category">{{category}}</option>
        </select>
      </div>
      <div class="form-group">
        <button type="submit" class="btn btn-primary btn-block">
          搜索
        </button>
      </div>
    </form>
    

    相关文章

      网友评论

          本文标题:模板式表单校验和 表单处理实战

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