精华内容
下载资源
问答
  • 响应式表单
    千次阅读
    2022-03-04 13:38:36
    一. 响应式表单

         响应式表单提供对底层表单对象模型直接、显式的访问。它们与模板驱动表单相比,更加健壮:它们的可扩展性、可复用性和可测试性都更高。如果表单是你的应用程序的关键部分,或者使用响应式表单来构建应用,那就使用响应式表单。

           使用  angular/forms 库中的 FormGroup, FormControl,FormArray,FormBuilder 等类构建出的数据对象就是响应式的表单, 在响应式的表单中,我们会在数据源里面进行各种操作,像添加校验等,在html文件中使用 formGroup,formGroupName,formControlName等将数据和视图进行绑定(需要引入ReactiveFormsModule)。

    1. 使用表单控件的几个步骤:
            定义及创建FormGroup;
            配置每个Control的验证规则;
            HTML添加FormControlName;
            获取表单数据;
            自定义验证规则;
            FormBuilder;
    也可以总结为两步:创建数据模型,使用指令将模板中的html元素连接到数据模型上
    数据模型是指一个用来保存表单数据的数据结构,它由定义在angular/forms模块中的三个类组成

    (1). FormControl
         是构成表单的基本单位,通常情况下用来代表一个 input 元素,也可以代表更复杂的UI组件,比如日历、下拉选择框。FormControl保存着与其关联的html元素当前的值、元素的校验状态以及元素是否被修改过等信息

    (2). FromGroup
         既可以代表表单的一部分,也可以代表整个表单,是多个FormControl的集合,将多个FormControl的值和状态聚合在一起,如果其中一个formcontrol是无效的,那整个FromGroup就是无效的

    (3). FormArray
         FormArray和FromGroup类似,但是他有一个长度属性,一般来说FormGroup用来代表整个表单,或者表单字段的固定子集(比如一个FromGroup里有两个FormControl分别是起始时间和结束时间); FormArray通常代表一个可以增长的字段集合,比如表单中有一个email字段,一个用户可能有多个Email,所以我们可以让用户输入任意多个email字段。

    export class ReactiveFormComponent implements OnInit {
       
       userName: FormControl = new FormControl('Jon');
    
       formModel: FormGroup = new FormGroup({  // FormGroup的构造函数是个对象
         startTime: new FormControl(), // key: startTime
         endTime: new  FormControl()
       )};
     
       emails: FormArray = new FormArray([ 
         // FormArray的构造函数是个数组,数组的每个元素是FormControl,与FormGroup不同的是,FormArray中的FormControl是没有相关的key的,通过数组下标来访问;
         new FormControl('258137@qq.com')   
         new FormControl('539451@qq.com')   
       ]);

    2. 响应式表单中的指令
     (1)  响应式表单的指令全部来自于ReactiveFoemsModule模块,我们在使用响应式表单上都会导入这个模块。

           类名

                 指令

    使用属性绑定时的指令

                          指令

     使用属性名字来连接数据模型和Dom元素

    FormGroupformGroupformGroupName
    FormControlformControlformControlName
    FormArrayformArrayName
    <input [formControl]="userName"> // formControl不能用在formGroup指令的内部,单独和input框绑定起来;若想把userName属性放进表单中来,就要把input框放进form元素标签内,并且用formControlName属性绑定。
    <form [formGroup]="formModel" (submit)="onSubmit()">    // formGroup的值是ts里的一个属性,要用属性绑定的语法[]绑定;
    <div  formGroupName="dateRange">   //formGroupName指令的值是个字符串,所以直接写个属性名就可以
       起始日期:<input type="date"  formControlName="from">  // formControlName必须声明在formGroup之内来连接formGroup中的formControl和页面上的DOM元素
       结束日期:<input type="date"  formControlName="to">
    </div>
    
    <div>
      <ul formArrayName="emails"> 
        <li *ngFor="let item of formModel.get('emails').controls; let i=index"> // i就是ngFor循环产生的循环下标的值
          <input type="text" [formControlName] = "i">
        </li>
      </ul>
     <button type="button" (click)="addEmail()">增加Email</button>
    </div>
    <div>
      <button type="submit">保存</button>
    </div>
    </form>
    export class ReactiveFormComponent implements OnInit {
      
      formModel: FormGroup = new FormGroup({
         dateRange: new FormGroup({
          from: new FormmControl(),
          to: new FormControl()
      }),
      emails: FormArray = new FormArray({  //FormArray中的FormControl没有名字,只有顺序号,所以一般情况下与ngFor指令一起使用;
        new FormControl("")
        new FormControl("")
        
      })
    });
    
     uesrName: FormControl = new FormControl("Jay") // 此时uesrName属性是不在表单的这个数据模型里面的,若想放进表单里,userName: new FormControl("Jay")
    
     constructor() {}
      
     ngOnInit() {}
    
     onSubmit() {
      console.log(this.formModel.value);
    }
    
     addEmail() {
      let emails = this.formModel.get("emails") as FormArray; //formModel.get("emails")拿到的是FormArray类型的对象,用as转型成formArray
      emails.push(new FormControl())
    }
    }

     (2)FormBuilder服务

         当需要与多个表单打交道时,手动创建多个表单控件实例会非常繁琐。FormBuilder服务提供了一些便捷方法来生成表单控件,简化了定义表单数据结构的语法,就相当于Angular提供的一个工具。
         通过以下步骤来实现这项服务:
     ①. 导入FormBuilder类,
     ②. 注入FormBuilder服务,
     ③. 生成表单内容。

    export class ReactiveFormComponent implements OnInit {
      formModel: FormGroup;
    
     constructor( fb: FormBuilder ) {
      this.formModel = fb.group({
         dateRange: fb.group({
          from: [''], // FormGroup还允许用数组来实例化一个formControl的实例,数组的第1个元素是formControl的初始值,第2个元素是校验方法,第3个元素是一个异步校验方法;多余的元素会被忽略。
          to: ['']
      }),
    });
    }
    }

    自定义验证器

          响应式表单的校验逻辑还可以以返回一个ValidatorFn类的函数(自定义验证器)实现的。

    function forbiddenNameValidator(value: string): ValidatorFn {
      return (control: AbstractControl): { [key: string]: any } | null => {
        const rule = new RegExp(value,'i');  // 设定验证规则,i是忽略大小写的意思
        const result = rule.test(control.value);  //control.value是输入框的值,forbidden是正则结果
        return result ? { 'forbiddenName': { value: control.value } } : null;  //如果匹配成功,则返回对象
      };
    }
    
    firstName:['',[forbiddenNameValidator('bob')]],

    2. 模板驱动表单

           简易理解:主要是html模板中使用指令(属性),适合简单的场景。对于html本身就有一些属性,比如最小值、最大值、规定type是number只能输入数字。

            模板驱动表单依赖模板中的指令来创建和操作底层的对象模型,。它们对于向应用添加一个简单的表单非常有用。模板驱动的表单是我们实例化好一个类的数据之后,在html中使用 NgForm 指令后将数据和表单进行绑定,使用[(ngModel)]来将表单的数据和和视图进行双向绑定,NgForm 指令为 form 增补了一些额外特性。 它会控制那些带有 ngModel 指令和 name 属性的元素,监听他们的属性。添加校验时要是用指令的方式,适合固定的输入表单。

     <div >
       <label for="power">Hero Power</label>
       <select id="power" class="form-control" required [(ngModel)]="model.power" name="power">
        <option *ngFor="let power of powers" [value]="power">{{power}}</option>
       </select>
      </div>

            可以简单理解成响应式表单是动态的,模板驱动表单是静态的。模板驱动表单适用于页面比较固定,例如登录页面,可以使用模板驱动表单。响应式表单适用于动态页面,通常都是维护一个formGroup,任何想要添加进来进行验证的组件,只要绑定一个formControl,然后加入到formGroup里,接下来的状态就可以通过formGroup来获取了。

    更多相关内容
  • Angular实现响应式表单

    2020-08-29 19:40:19
    本篇文章主要介绍了Angular实现响应式表单,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了详解Angular2响应式表单,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了angular6的响应式表单的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 这是一款使用html5表单验证新属性制作的HTML5超酷响应式表单美化模板插件。该html5表单美化插件可以使用html5新特性栏验证表单,表单整体效果趋于扁平化风格,非常好看。
  • angular 响应式表单

    2021-09-24 14:44:37
    响应式表单 Angular 提供了两种不同的方法来通过表单处理用户输入:响应式表单和模板驱动表单。 响应式表单:提供对底层表单对象模型直接、显式的访问。它们与模板驱动表单相比,更加健壮。如果表单是你的应用程序...

    响应式表单

    Angular 提供了两种不同的方法来通过表单处理用户输入:响应式表单模板驱动表单

    • 响应式表单:提供对底层表单对象模型直接、显式的访问。它们与模板驱动表单相比,更加健壮。如果表单是你的应用程序的关键部分,或者你已经在使用响应式表单来构建应用,那就使用响应式表单。
    • 模板驱动表单:依赖模板中的指令来创建和操作底层的对象模型。它们对于向应用添加一个简单的表单非常有用,比如电子邮件列表注册表单。

    这里只介绍响应式表单,模板驱动表单请参考官网—https://angular.cn/guide/forms-overview#setup-in-template-driven-forms

    全局注册响应式表单模块 ReactiveFormsModule

    要使用响应式表单控件,就要从 @angular/forms 包中导入 ReactiveFormsModule,并把它添加到你的 NgModuleimports数组中。如下:app.module.ts

    /***** app.module.ts *****/
    import { ReactiveFormsModule } from '@angular/forms';
    
    @NgModule({
      imports: [
        // other imports ...
        ReactiveFormsModule
      ],
    })
    export class AppModule { }
    

    添加基础表单控件 FormControl

    使用表单控件有三个步骤。

    1. 在你的应用中注册响应式表单模块。该模块声明了一些你要用在响应式表单中的指令。
    2. 生成一个新的 FormControl 实例,并把它保存在组件中。
    3. 在模板中注册这个 FormControl

    要注册一个表单控件,就要导入FormControl类并创建一个 FormControl的新实例,将其保存为类的属性。如下:test.component.ts

    /***** test.component.ts *****/
    import { Component } from '@angular/core';
    import { FormControl } from '@angular/forms';
    
    @Component({
      selector: 'app-name-editor',
      templateUrl: './name-editor.component.html',
      styleUrls: ['./name-editor.component.css']
    })
    export class TestComponent {
    	// 可以在 FormControl 的构造函数设置初始值,这个例子中它是空字符串
      name = new FormControl('');
    }
    

    然后在模板中注册该控件,如下:test.component.html

    <!-- test.component.html -->
    <label>
      Name: <input type="text" [formControl]="name">
    </label>
    <!-- input 中输入的值变化的话,这里显示的值也会跟着变化 -->
    <p>name: {{ name.value }}</p>
    

    FormControl 的其它属性和方法,参阅 API 参考手册

    把表单控件分组 FormGroup

    就像FormControl 的实例能让你控制单个输入框所对应的控件一样,FormGroup 的实例也能跟踪一组 FormControl 实例(比如一个表单)的表单状态。当创建 FormGroup 时,其中的每个控件都会根据其名字进行跟踪。

    看下例演示:test.component.tstest.component.html

    import { Component } from '@angular/core';
    import { FormControl, FormGroup, Validators } from '@angular/forms'
    
    @Component({
      selector: 'app-test',
      templateUrl: './test.component.html',
      styleUrls: ['./test.component.css']
    })
    export class TestComponent implements OnInit {
        constructor() {}
    
        profileForm = new FormGroup({
          firstName: new FormControl('', [Validators.required,Validators.pattern('[a-zA-Z0-9]*')]),
          lastName: new FormControl('', Validators.required),
        });
    	
    	onSubmit() {
    		// 查看控件组各字段的值
          console.log(this.profileForm.value)
        }
    }
    
    <!-- profileForm 这个 FormGroup 通过 FormGroup 指令绑定到了 form 元素,在该模型和表单中的输入框之间创建了一个通讯层 -->
    <!-- FormGroup 指令还会监听 form 元素发出的 submit 事件,并发出一个 ngSubmit 事件,让你可以绑定一个回调函数。 -->
    <form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
        <label>
    <!-- 由 FormControlName 指令把每个输入框和 FormGroup 中定义的表单控件 FormControl 绑定起来。这些表单控件会和相应的元素通讯 -->
          First Name: <input type="text" formControlName="firstName">
        </label>
        <label>
          Last Name: <input type="text" formControlName="lastName">
        </label>
        <button type="submit" [disabled]="!profileForm.valid">Submit</button>
      </form>
    
      <p>{{ profileForm.value }}</p>
      <!-- 控件组的状态: INVALID 或 VALID -->
      <p>{{ profileForm.status }}</p>	
      <!-- 控件组输入的值是否为有效值: true 或 false-->
      <p>{{ profileForm.valid }}</p>
      <!-- 是否禁用: true 或 false-->
      <p>{{ profileForm.disabled }}</p>
    

    FormGroup 的其它属性和方法,参阅 API 参考手册

    使用更简单的 FormBuilder 服务生成控件实例

    在响应式表单中,当需要与多个表单打交道时,手动创建多个表单控件实例会非常繁琐。FormBuilder服务提供了一些便捷方法来生成表单控件。FormBuilder在幕后也使用同样的方式来创建和返回这些实例,只是用起来更简单。

    FormBuilder 是一个可注入的服务提供者,它是由 ReactiveFormModule 提供的。只要把它添加到组件的构造函数中就可以注入这个依赖。

    FormBuilder服务有三个方法:control()group()array()。这些方法都是工厂方法,用于在组件类中分别生成FormControlFormGroupFormArray

    看下例演示:test.component.ts

    import { Component } from '@angular/core';
    // 1、导入 FormBuilder
    import { FormBuilder, Validators } from '@angular/forms';
    
    @Component({
      selector: 'app-test',
      templateUrl: './test.component.html',
      styleUrls: ['./test.component.css']
    })
    export class TestComponent {
    	// 2、注入 FormBuilder 服务
        constructor(private fb: FormBuilder) { }
        ngOnInit() { }
    
        profileForm = this.fb.group({
          firstName: ['', [Validators.required, Validators.pattern('[a-zA-Z0-9]*')]],
          lastName: ['', Validators.required],
        });
        // 相当于
        // profileForm = new FormGroup({
        //   firstName: new FormControl('', [Validators.required,Validators.pattern('[a-zA-Z0-9]*')]),
        //   lastName: new FormControl('', Validators.required),
        // });
    
        onSubmit() {
          console.log(this.profileForm.value)
          console.log(this.profileForm)
        }
    }
    

    对比可以发现,使用FormBuilder服务可以更方便地生成FormControlFormGroupFormArray,而不必每次都手动new一个新的实例出来。

    表单验证器 Validators

    Validators类验证器的完整API列表,参考API手册

    验证器(Validators)函数可以是同步函数,也可以是异步函数。

    • 同步验证器:这些同步函数接受一个控件实例,然后返回一组验证错误或 null。你可以在实例化一个 FormControl 时把它作为构造函数的第二个参数传进去。
    • 异步验证器 :这些异步函数接受一个控件实例并返回一个 PromiseObservable,它稍后会发出一组验证错误或 null。在实例化 FormControl 时,可以把它们作为第三个参数传入。

    出于性能方面的考虑,只有在所有同步验证器都通过之后,Angular 才会运行异步验证器。当每一个异步验证器都执行完之后,才会设置这些验证错误。

    验证器Validators类的API

    https://angular.cn/api/forms/Validators

    class Validators {
      static min(min: number): ValidatorFn		// 允许输入的最小数值
      static max(max: number): ValidatorFn		// 最大数值
      static required(control: AbstractControl): ValidationErrors | null	// 是否必填
      static requiredTrue(control: AbstractControl): ValidationErrors | null
      static email(control: AbstractControl): ValidationErrors | null	// 是否为邮箱格式
      static minLength(minLength: number): ValidatorFn		// 最小长度
      static maxLength(maxLength: number): ValidatorFn		// 最大长度
      static pattern(pattern: string | RegExp): ValidatorFn	// 正则匹配
      static nullValidator(control: AbstractControl): ValidationErrors | null	// 什么也不做
      static compose(validators: ValidatorFn[]): ValidatorFn | null
      static composeAsync(validators: AsyncValidatorFn[]): AsyncValidatorFn | null
    }
    

    内置验证器函数

    要使用内置验证器,可以在实例化FormControl控件的时候添加

    import { Validators } from '@angular/forms';
    ...
    ngOnInit(): void {
      this.heroForm = new FormGroup({
      // 实例化 FormControl 控件
        name: new FormControl(this.hero.name, [
          Validators.required,	// 验证,必填
          Validators.minLength(4),	// 长度不小于4
          forbiddenNameValidator(/bob/i) // 自定义验证器
        ]),
        alterEgo: new FormControl(this.hero.alterEgo),
        power: new FormControl(this.hero.power, Validators.required)
      });
    }
    get name() { return this.heroForm.get('name'); }
    
    get power() { return this.heroForm.get('power'); }
    

    自定义验证器

    自定义验证器的内容请参考API手册

    有时候内置的验证器并不能很好的满足需求,比如,我们需要对一个表单进行验证,要求输入的值只能为某一个数组中的值,而这个数组中的值是随程序运行实时改变的,这个时候内置的验证器就无法满足这个需求,需要创建自定义验证器。

    • 在响应式表单中添加自定义验证器。在上面内置验证器一节中有一个forbiddenNameValidator函数如下:

      import { Validators } from '@angular/forms';
      ...
      ngOnInit(): void {
        this.heroForm = new FormGroup({
          name: new FormControl(this.hero.name, [
            Validators.required,
            Validators.minLength(4),
            // 1、添加自定义验证器
            forbiddenNameValidator(/bob/i)
          ])
        });
      }
      // 2、实现自定义验证器,功能为禁止输入带有 bob 字符串的值
      export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
          const forbidden = nameRe.test(control.value);
          // 3、在值有效时返回 null,或无效时返回验证错误对象
          return forbidden ? {forbiddenName: {value: control.value}} : null;
        };
      }
      

      验证器在值有效时返回 null,或无效时返回验证错误对象。 验证错误对象通常有一个名为验证秘钥(forbiddenName)的属性。其值为一个任意词典,你可以用来插入错误信息({name})。

    • 在模板驱动表单中添加自定义验证器。要为模板添加一个指令,该指令包含了 validator 函数。同时,该指令需要把自己注册成为NG_VALIDATORS的提供者。如下所示:

      // 1、导入相关类
      import { NG_VALIDATORS, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
      import { Input } from '@angular/core'
      
      @Directive({
        selector: '[appForbiddenName]',
        // 2、注册成为 NG_VALIDATORS 令牌的提供者
        providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
      })
      export class ForbiddenValidatorDirective implements Validator {
        @Input('appForbiddenName') forbiddenName = '';
        // 3、实现 validator 接口,即实现 validate 函数
        validate(control: AbstractControl): ValidationErrors | null {
        	// 在值有效时返回 null,或无效时返回验证错误对象
          return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
                                    : null;
        }
      }
      // 4、自定义验证函数
      export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
          const forbidden = nameRe.test(control.value);
          // 3、在值有效时返回 null,或无效时返回验证错误对象
          return forbidden ? {forbiddenName: {value: control.value}} : null;
        };
      }
      

      注意,自定义验证指令是用 useExisting 而不是 useClass 来实例化的。如果用useClass来代替 useExisting,就会注册一个新的类实例,而它是没有forbiddenName 的。

      <input type="text" required appForbiddenName="bob" [(ngModel)]="hero.name">
      
    展开全文
  • Angular响应式表单

    2022-03-20 12:44:55
    Angular响应式表单的控制逻辑写在组件类中,对验证逻辑有更多的控制权,适合复杂表单类型。 一、Angular响应式表单基本用法 FormGroup:表单组,表单至少是一个FormGroup FormControl:表单组的一个表单项 1、引入...

    Angular响应式表单的控制逻辑写在组件类中,对验证逻辑有更多的控制权,适合复杂表单类型。
    一、Angular响应式表单基本用法
    FormGroup:表单组,表单至少是一个FormGroup
    FormControl:表单组的一个表单项
    1、引入ReactiveFormsModule

    import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { TemplateFormsComponent } from './components/templateForms/templateForms.component';
    import { ReativeFormsComponent } from './components/reativeForms/reativeForms.component';
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    
    @NgModule({
      imports: [
        CommonModule,
        FormsModule,
        ReactiveFormsModule
      ],
      declarations: [
        TemplateFormsComponent,
        ReativeFormsComponent
      ],
      exports: [
        TemplateFormsComponent,
        ReativeFormsComponent
      ]
    })
    export class ThreeFormsModule { }
    

    2、在组件类中创建FormsGroup表单控制对象

    import { Component, OnInit } from '@angular/core';
    import { FormControl, FormGroup } from '@angular/forms';
    
    @Component({
      selector: 'app-reativeForms',
      templateUrl: './reativeForms.component.html',
      styleUrls: ['./reativeForms.component.less']
    })
    export class ReativeFormsComponent implements OnInit {
      personMes: FormGroup=new FormGroup({
        name: new FormControl(),
        address: new FormControl()
      })
      constructor() { }
      ngOnInit() {
      }
      OnSubmit(){
        console.log(this.personMes.value)
      }
    }
    

    3、关联组件模板中的表单

    <form [formGroup]="personMes" (submit)="OnSubmit()">
      <input type="text" formControlName="name"><br>
      <input type="text" formControlName="address"><br>
      <button>提交</button>
    </form>
    

    4、效果
    在这里插入图片描述
    二、Angular响应式表单分组
    1、在模板中增加formGropName,在组件类中personMes表单对象new FormGroup子对象

    <form [formGroup]="personMes" (submit)="OnSubmit()">
      <div formGroupName="nameList">
        <input type="text" formControlName="name"><br>
      </div>
      <input type="text" formControlName="address"><br>
      <button>提交</button>
    </form>
    
    export class ReativeFormsComponent implements OnInit {
      personMes: FormGroup=new FormGroup({
        nameList: new FormGroup({ name: new FormControl()
    }),
        address: new FormControl()
      })
      constructor() { }
    
      ngOnInit() {
      }
      OnSubmit(){
        console.log(this.personMes.value)
        console.log(this.personMes.value.nameList.name)
      }
    }
    

    2、效果
    在这里插入图片描述

    三、Angular响应式表单验证
    Angular响应式表单有内置验证、自定义验证。内置验证方法有,Validators.required(内容不可为空)、Validators.minLength()(内容最小长度)、Validators.maxLength()(内容最大长度)。自定义验证方法分为同步验证和异步验证,同步验证主要验证正则表达规则,异步验证主要与服务器交互,例如查询呢称是否重名。
    1、内置验证

    <form [formGroup]="personMes" (submit)="OnSubmit()">
      <input type="text" formControlName="name"><br>
      <ng-container *ngIf="name?.touched&&name?.invalid&&name?.errors">
      <div *ngIf="name?.errors?.required">内容不能为空</div>
      <div *ngIf="name?.errors?.minlength">长度不可小于2</div>
      </ng-container>
      <input type="text" formControlName="address"><br>
      <button>提交</button>
    </form>
    
    export class ReativeFormsComponent implements OnInit {
      personMes: FormGroup=new FormGroup({
        name: new FormControl("",[Validators.required,Validators.minLength(2)]),
        address: new FormControl()
      })
      get name() {
        return this.personMes.get("name")
      }
      constructor() { }
    
      ngOnInit() {
      }
      OnSubmit(){
        console.log(this.personMes.value)
      }
    }
    

    效果:
    在这里插入图片描述
    在这里插入图片描述
    2、同步类型自定义验证
    创建自定义验证器,class myValidators,内部自定义方法必须是静态方法。

    <form [formGroup]="personMes" (submit)="OnSubmit()">
      <input type="text" formControlName="name"><br>
      <ng-container *ngIf="name?.touched&&name?.invalid&&name?.errors">
      <div *ngIf="name?.errors?.required">内容不能为空</div>
      <div *ngIf="name?.errors?.minlength">长度不可小于2</div>
      <div *ngIf="name?.errors?.isENG">必须为大写字母</div>
      </ng-container>
      <input type="text" formControlName="address"><br>
      <button>提交</button>
    </form>
    
    import { AbstractControl } from "@angular/forms";
    //自定义验证规则
    export class myValidators {
       static isENG(formControl: AbstractControl){
           if(/[A-Z]+/.test(formControl.value)){
               return { isENG: false}
           }else{
               return { isENG: true }
           }
       }
    }
    
    export class ReativeFormsComponent implements OnInit {
      personMes: FormGroup=new FormGroup({
        name: new FormControl("",[Validators.required,Validators.minLength(2),myValidators.isENG]),
        address: new FormControl()
      })
      get name() {
        return this.personMes.get("name")
      }
      constructor() { }
    
      ngOnInit() {
      }
      OnSubmit(){
        console.log(this.personMes.value)
      }
    }
    

    效果
    在这里插入图片描述
    3、异步类型自定义验证
    在创建自定义验证器class myValidators中新创建静态方法isUnique,方法的返回值一定要是Promise或Obserable或null,在name: new FormControl中注册异步验证,在html中name?.errors?.isUnique判断值是否为true,为true则显示用户名已存在,否则通过验证。

    <form [formGroup]="personMes" (submit)="OnSubmit()">
      <input type="text" formControlName="name"><br>
      <ng-container *ngIf="name?.touched&&name?.invalid&&name?.errors">
        <div *ngIf="name?.errors?.required">内容不能为空</div>
        <div *ngIf="name?.errors?.minlength">长度不可小于2</div>
        <div *ngIf="name?.errors?.isENG">必须为大写字母</div>
        <div *ngIf="name?.errors?.isUnique">用户名已存在</div>
      </ng-container>
      <div *ngIf="name?.pending">验证中...</div>
      <input type="text" formControlName="address"><br>
      <button>提交</button>
    </form>
    
    export class ReativeFormsComponent implements OnInit {
      personMes: FormGroup=new FormGroup({
        name: new FormControl(
          "", [Validators.required, Validators.minLength(2), myValidators.isENG], myValidators.isUnique
            // asyncValidators: [this.myValidatorst.validate.bind(this.myValidatorst)]
          ),
        address: new FormControl()
      }, )
      get name() {
        return this.personMes.get("name")
      }
      constructor(private myValidatorst: myValidatorsT ) { }
    
      ngOnInit() {
      }
      OnSubmit(){
        console.log(this.personMes.value)
        console.log(this.name)
      }
    }
    
    static isUnique(formControl: AbstractControl):Promise<ValidationErrors> {
           return new Promise(function(resolve){
               setTimeout(function(){
                   if(formControl.value=="ADM"){
                        resolve({isUnique: true})
                   }else{
                        resolve({ isUnique: false })
                   }
               },2000)
           })
        }
    

    效果
    在这里插入图片描述
    在这里插入图片描述
    四、创建Angular响应式表单的快捷方式——FormBuilder
    在constructor中注入FormBuilder服务,简化操作,无需new FormGroup和new FormControl

    export class ReativeFormsComponent implements OnInit {
      personMes!: FormGroup;
      get name() {
        return this.personMes.get("name")
      }
      constructor(private fb: FormBuilder) {
        this.personMes =this.fb.group({
          name: [
            "", [Validators.required, Validators.minLength(2), myValidators.isENG], myValidators.isUnique
            // asyncValidators: [this.myValidatorst.validate.bind(this.myValidatorst)]
          ],
          address: [""]
        })
      }
    
      ngOnInit() {
      }
      OnSubmit(){
        console.log(this.personMes.value)
        console.log(this.name)
      }
    }
    

    效果和上一例一样

    展开全文
  • 主要介绍了angular中两种表单的区别(响应式和模板驱动表单),详细的介绍了这两种表单的实现以及区别,非常具有实用价值,需要的朋友可以参考下
  • 众所周知Angular响应式表单相比较模板驱动表单更大操作性、更易测试性。因此,我更推荐这类表单创造方式。 当一个用于修改用户信息的表单,数据的来源总是来自远程;而对于一个 FormGroup 的创建总在 ngOnInit 中...
  • 响应式表单组件布局

    千次阅读 2022-03-11 22:41:56
    响应式表单组件布局,表单一行能放下多少就多少,会响应式的控制

    一、实现

    // 响应式表单
    @mixin global-form(
      $width: 420px,
      $gridGap: 24px,
      $innerWidth: 240px,
      $labelWidth: 100px
    ) {
      background: #ffffff;
      border-radius: 0 0 4px 4px;
      padding: 24px 0 8px 0;
      margin: 0;
      margin-top: 0;
      color: #323e58;
      font-size: 12px;
    
      .grid-form {
        display: grid;
        justify-content: space-between;
        grid-template-columns: repeat(auto-fill, $width);
        grid-gap: $gridGap;
      }
    
      & > *:not(:first-child) {
        padding-top: $gridGap;
      }
    
      .el-form-item {
        font-size: 12px;
      }
    
      /deep/.el-form-item__content {
        width: max-content;
      }
    
      /deep/.el-input__inner {
        height: 32px;
      }
    
      // 普通输入框
      /deep/.el-input__inner,
      /deep/.el-textarea__inner {
        width: $innerWidth;
        font-size: 12px;
        border: 1px solid #d7dbe8;
        &::placeholder {
          color: #c5cad5;
        }
      }
      // select输入框
      // /deep/.el-select .el-input__inner {
      //   width: 115px;
      // }
    
      /deep/.el-textarea .el-input__count {
        bottom: 0;
        background: transparent;
      }
    
      /deep/.el-input__count-inner {
        color: #c5cad5;
      }
    
      /deep/.el-form-item__label,
      /deep/.el-radio__label {
        font-size: 12px;
        color: #323e58;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    
      /deep/.el-form-item--small.el-form-item {
        margin: 0;
      }
    
      /deep/.el-radio-group {
        max-width: 300px;
      }
    
      // 上传图片的提示
      .upload-tips {
        width: max-content;
        margin-top: 8px;
        color: #858b9c;
        font-size: 12px;
        line-height: 18px;
      }
    
      // 自定义提示(一直都存在)
      .custom-tip {
        padding-top: 4px;
        font-size: 12px;
        color: #c5cad5;
        line-height: 22px;
    
        .btn-text {
          color: #2a65e9;
          cursor: pointer;
        }
      }
    
      // 富文本编辑器
      .form-editor {
        position: relative;
        // width: calc(100vw / 1440 * 1104);
        width: calc(100% - #{$labelWidth});
        z-index: 0;
    
        /deep/.w-e-toolbar {
          border-radius: 4px 4px 0 0;
        }
    
        /deep/.w-e-text-container {
          border-radius: 0 0 4px 4px;
        }
    
        /deep/.placeholder {
          color: #c5cad5;
          font-size: 12px;
        }
        /deep/ .w-e-toolbar p,
        /deep/ .w-e-text-container p,
        /deep/ .w-e-menu-panel p {
          font-size: 12px !important;
          color: #323e58;
        }
      }
    
      // 填满剩余宽度(除去label的宽度),加在form-item上面
      .fill-width {
        /deep/.el-form-item__content {
          width: calc(100% - #{$labelWidth});
        }
    
        /deep/.el-input__inner,
        /deep/.el-textarea__inner {
          width: 100%;
        }
      }
    }
    

    二、使用模板

    <template>
        <!-- form-cnt类名自定义即可 -->
        <el-form class="form-cnt">
            <!-- 自适应的form-item列表 -->
            <div class="grid-form">
                <el-form-item />
                ...
            </div>
            <!-- 单独一行的form-item -->
            <el-form-item />
            ...
        </el-form>
    </template>
    
    <!-- 注意这里style标签必须得同下,必须带scoped -->
    <style lang="scss" scoped>
        . form-cnt {
            // 不带参数,使用默认值
            @include global-form;
            // 带参数
            @include global-form(340px)
        }
    </style>
    

    三、参数说明

    global-form($width: 420px, $gridGap: 24px, $innerWidth: 240px, $labelWidth: 100px)
    

    $width : el-form的总体宽度

    $gridGap : el-form之间的间隙,统一为24px

    $innerWidth: el-input__inner的宽度

    $labelWidth: 100px: el-form-item__label的宽度,用于计算表单占满宽度的

    以后可能修改:按理来说,$width是不需要传的,是通过$innerWidth$labelWidth计算就可以了

    四、特殊情况说明

    global-form 中已对大部分表单类型进行适配,对于global-form 中没有定义过的表单类,可以在mixin下面进行全局修改,如果修改后影响到其他页面的需要特殊处理,不可全局修改。

    原则:保持全局一致性,特殊情况特殊处理(过多特殊情况是不可取的)

    五、参考示例

    涉及到公司的设计规范就不拿出来了

    六、总结(题外话)

    这是感觉UI规范和具体的业务编写的一套定制化代码,所以并不适合所有人,这里只是记录以下工作的东西。而且上面整个文档在公司都是有这个文档的,内容基本一致。

    展开全文
  • 本篇博客阐述Angular响应式表单的基本使用。
  • 响应式表单

    2019-02-11 15:51:31
    FormControl: 表单中的每一个item userName: FormControl = new FormControl('aaa') FormGroup: 表单数据分组,可以嵌套 formModel: FormGroup = new FormGroup({ from: new FormControl(), to: new Form...
  • css3响应式表单制作留言表单提交代码
  • angular8响应式表单,表单验证,异步验证 响应式表单 Angular 提供了两种不同的方式来创建表单处理用户输入:响应式表单和模板驱动表单。 响应式表单和模板驱动表单共享了一些底层构造块。 FormControl 实例用于追踪...
  • angular7中响应式表单校验

    千次阅读 2019-07-03 11:39:24
    响应式表单校验(angular自带校验和自定义校验规则) import { Component, OnInit } from '@angular/core'; import { FormBuilder, Validators, FormControl, FormGroup } from '@angular/forms'; import { fbind } ...
  • Angular-Forms模板驱动表单、响应式表单、动态表单、表单验证
  • Angular—模板式表单和响应式表单

    千次阅读 2019-05-19 21:42:19
    1. 模板式表单和响应式表单的不同点
  • Angular 的响应式表单

    2017-08-03 22:54:47
    摘要:本文简单介绍 Angular 的响应式表单,还是以之前的评论模块为例 介绍Angular 总共提供了 3 中表单实现方式,分别是:Template-driven Forms (模板驱动表单)、 Reactive Forms (响应式表单)、Dynamic Forms...
  • 之前我们利用CSS3自定义Checkbox和自定义Radiobox,这次要分享的一款CSS3响应式表单不仅美化了checkbox和Radiobox,而且也自定义美化了输入框、下拉框以及多项选择框,几乎所有的表单元素都美化了,而且整体上还不错...
  • angular7+ngzorro响应式表单验证

    千次阅读 2019-07-03 11:41:46
    使用响应式表单在开发的过程中,经常会用到。使用响应式表单的不仅能够提高开发效率,并且还能有效减少冗余的代码,在表单校验的时候也更方面,并且结合ngzorro进行表单校验效果更完美。 ...
  • Chart.js 是一个基于 HTML5 canvas 的响应式、灵活的、轻量化的图表库。库中提供了六种不同的图表类型,每种类型都带有一系列的自定义选项。如果这些还不够,你还可以创造自己的图表类型。 Chart.js 的六种图表类型...
  • 时尚多表单响应式网页模板
  • jquery登录注册忘记密码响应式表单验证特效html模板.zip
  • 一个Angular示例应用程序,包括使用HttpClient服务选​​择,添加,更新和删除数据,对象和数组类型的React形式,内联数据列表编辑,自定义输入验证以及各种其他功能(使用Angular 11 CLI和ASP.NET Core 5.0)。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 71,314
精华内容 28,525
关键字:

响应式表单

友情链接: StuMSys.rar