关闭

Angular 响应式表单之表单分组

时间: 2019-02-23阅读: 1271标签: Angular

1、案例需求

表单提交,表单全部校验成功才能提交,当表单校验错误,表单边框变红,同时有错误提示信息,有重置功能


2、名词解释

在分析代码之前,首先明确 FormControl、formControl、formControlName、FormGroup、formGroup、formGroupName、FormArray、formArray、formArrayName 都是什么意思以及它们的用法。

2.1、FormControl

  • FormControl:跟踪独立表单控件的值和验证状态。它和 FormGroup 和 FormArray 是 Angular 表单的三大基本构造块之一。它扩展了 AbstractControl 类,并实现了关于访问值、验证状态、用户交互和事件的大部分基本功能。

当使用响应式表单时,FormControl 类是最基本的构造块。要注册单个的表单控件,在组件中导入 FormControl 类,并创建一个 FormControl 的新实例,把它保存在类的某个属性中。

export class AppComponent implements OnInit {
    const control = new FormControl('', Validators.required);
    console.log(control.value);      // ''
    console.log(control.status);     // 'INVALID'
}

在组件类中创建了控件之后,还要把它和模板中的一个表单控件关联起来,为表单控件添加 formControl 绑定。

<label>
  Name:
  <input type="text" [formControl]="name">
</label>
  • formControl:是一个输入指令,接受 FormControl 的实例,在模版中使用。
  • formControlName: 也是输入指令,但是它接受的是一个字符串,同 formGroup 指令配合使用。
<div>
  <input type="text" [formControl]="myForm.controls.firstName"/>
  <input type="text" [formControl]="myForm.controls.lastName"/>
  <input type="text" [formControl]="myForm.controls.email"/>
  <input type="text" [formControl]="myForm.controls.title"/>
</div>

//等同于

<div [formGroup]="myForm">
  <input type="text" formControlName="firstName"/>
  <input type="text" formControlName="lastName"/>
  <input type="text" formControlName="email"/>
  <input type="text" formControlName="title"/>
</div>

2.2、FormGroup

  • FormGroup:跟踪一组 FormControl 实例的值和有效性状态

FormGroup 把每个子 FormControl 的值聚合进一个对象,它的 key 是每个控件的名字。它通过归集其子控件的状态值来计算出自己的状态。如果组中的任何一个控件是无效的,那么整个组就是无效的。

2.3、FormArray

  • FormArray:跟踪一个控件数组的值和有效性状态

FormArray 聚合了数组中每个表单控件的值。它会根据其所有子控件的状态总结出自己的状态。如果 FromArray 中的任何一个控件是无效的,那么整个数组也会变成无效的。

  • FormControl、FormGroup、FormArray 类 用法一致
  • formControl、formGroup、formArray 输入指令 值为对应类的实例 用法一致
  • formControlName、formGroupName、formArrayName 输入指令 值为字符串 用法一直


3、代码分析

fromGroup 可以然我们对表单内容进行分组,方便我们在语义上区分不同类型的输入,本例中,地址细分为“省”、“市”、“区”。

this.formGroup = this.fb.group({
      name: ['', nameValidator()],
      age: ['', ageValidator()],
      sex: ['', sexValidator()],
      address: this.fb.group({
        province: ['', requiredValidator('请输入省')],
        city: ['', requiredValidator('请输入市')],
        district: ['', requiredValidator('请输入区')]
      })
    });

address 此时不是 fromControl 而是 formGroup。

<div class="form-group"
    formGroupName="address">
    <label>地址:</label>
    <div>
      <label>省:</label>
      <input type="text"
        formControlName="province">
      <p>{{errorMessage('province')}}</p>
    </div>
    <div>
      <label>市:</label>
      <input type="text"
        formControlName="city">
      <p>{{errorMessage('city')}}</p>
    </div>
    <div>
      <label>区:</label>
      <input type="text"
        formControlName="district">
      <p>{{errorMessage('district')}}</p>
    </div>
  </div>

在获取 省市区的 formControl 时,可以通过这样获取

// 太复杂了
this.formGroup.controls['address'].controls['province'];

// 同样复杂
this.formGroup.get('address').controls['province'];

// 还好
this.formGroup.get(['address', 'province']);

第三种方式虽然简单,但是不够完美,get方法不能一步到位,必须同时传入 formGroupName 和 formControlName。因此在查看单个表单是否有错误信息时,必须先判断 formControlName 是子组件还是孙子组件。

errorMessage(formControlName: string): string {

    let control: AbstractControl;

    if (this.formGroup.contains(formControlName)) {
      control = this.formGroup.get(formControlName);
    } else {
      control = this.formGroup.get(['address', formControlName]);
    }
    return ((control.touched || control.dirty) && control.invalid) ? control.errors.message : '';
  }

contains方法:检查组内是否有一个具有指定名字的已启用的控件,存在返回 true,不存在返回 false。

来自:https://segmentfault.com/a/1190000018249859


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: http://www.fly63.com/article/detial/2092

AngularJS 的那些内置九种过滤器

ng内置了九种过滤,currency (货币处理)使用currency可以将数字格式化为货币,默认是美元符号,你可以自己传入所需的符号,例如我传入人民币,ng提供的date过滤器基本可以满足一般的格式化要求。

Angular deploy 的实现

Angular CLI 在 8.3.0 发布过一个新命令 ng deploy,可以将 Angular 应用部署到远程服务器或云存储上面,例如:Firebase hosting、Azure、GitHub pages 等等,这也是算是 Angular CLI 最后一个将 Angular 应用从开发到部署打通全能选手工具了。

20 个 AngularJS 开发工具

AngularJS是那些渴望以动态方式来设计web app的web开发人员最偏爱的框架之一。如果你是一个希望启动AngularJS项目的开发人员,那么你可能需要帮助来挑选出趁手的工具……

Angular HMR(热模块替换)功能实现方法

在使用Angular的时候,希望能像VUE那样,修改代码后浏览器不刷新,页面对应修改的组件自动更新的功能。这个功能的名字时HMR (hot module replace)。稍微研究了一下,发现在angular/cli创建的项目中,实现这个不算太难,步骤如下

angular有必要学吗?

对于前端开发人员来说,angular是非常有必要学习的,它可以使Web应用开发比以往更简单、更快捷;同时也降低了构建复杂应用的难度。更何况很多后端职位都要求掌握angular了。Angular是一个使用 HTML 和 JavaScript 编写的 Web 前端框架

angular7中的变化监测

最近做公司新项目用的angular7,中碰到了一个很头疼的问题在绑定对象中的数据改变时,页面视图没有跟新,需点击页面中的时间元素后才会更新。

AngularJS中几种Providers的区别

AngularJS文档对provider的定义:provider是一个带有$get()方法的对象。injector调用$get方法创建一个新的service的实例。provider还有一些其他的方法,可以用来配置provider。

angular.js和vue.js中实现函数去抖

搜索输入框中,只当用户停止输入后,才进行后续的操作,比如发起Http请求等。本文将分别探讨在angular.js和vue.js中如何实现对用户输入的防抖。

Angular有哪些版本?

目前Angular有7个版本,分别为:AngularJS、Angular2、Angular4、Angular5、Angular6、Angular7、Angular8。下面本篇文章就来给大家介绍一下,希望对大家有所帮助。

你所要知道的所有关于Angular的变化检测机制

如果想像我一样全面的了解Angular的脏值检测机制,除了浏览源代码之外别无他法,网上可没有太多可用信息。大部分文章都提到,Angular中每个组件都自带一个脏值检测器,但是它们都仅仅停留在脏值检测的策略和案例的使用,并没有做太多的深入。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!