NgForm学习笔记

从废弃的 ngForm 选择器迁移过来监听表单提交设置更新选项NgForm与NgModelngModel[ngModel][(ngModel)]参考文献javascript

NgForm 建立一个顶级的 FormGroup 实例,并把它绑定到一个表单,以跟踪表单的聚合值及其验证状态。 html

官方文档说明:java

只要你导入了 FormsModule,该指令就会默认在全部web

标签上生效。你不须要再添加任何特殊的选择器。

你能够以 ngForm 做为 key 把该指令导出到一个局部模板变量(如 #myForm="ngForm")。这是可选的,但颇有用。 来自本指令背后的 FormGroup 实例的不少属性,都被复制到了指令自身,因此拿到一个对该指令的引用就可让你访问此表单的聚合值和验证状态, 还有那些用户交互类的属性,好比 dirtytouchedjson

若是须要,还能够监听该指令的 ngSubmit 事件,以便当用户触发了一次表单提交时获得通知。发出 ngSubmit 事件时,会携带原始的 DOM 表单提交事件。app

在模板驱动表单中,全部 标签都会自动应用上 `NgForm` 指令。 若是你只想导入 `FormsModule` 而不想把它应用于某些表单中,好比,要想使用 HTML5 验证,你能够添加 `ngNoForm` 属性, 这样标签就不会在 上建立 NgForm 指令了。 在响应式表单中,则不须要用 ngNoForm,由于 NgForm 指令不会自动应用到 ` 标签上,你只要别主动添加formGroup` 指令就能够了。post

从废弃的 ngForm 选择器迁移过来

ngForm 元素选择器的支持已经在 Angular v6 中废弃,并将在 Angular v9 中移除。性能

之因此弃用它,是咱们要让全部选择器都跟其它核心 Angular 选择器保持统一,而元素选择器一般写做中线格式。测试

已废弃的写法:ui

<ngForm #myForm="ngForm">
复制代码

之后的写法:

<ng-form #myForm="ngForm">
复制代码

监听表单提交

下面的示例显示如何从“ ngSubmit”事件捕获表单值。

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
    <h2>Listening for form submission</h2>

    <form  (ngSubmit)="onSubmit(f)" #f="ngForm" novalidate >
      <label>First Name: <input name="first" ngModel required #first="ngModel" /></label>
      <br>
      <label>Last Name: <input name="last" ngModel /></label>
      <br>
      <button>Submit</button>
    </form>

    <div>
      <p>First name value: {{ first.value }}</p>
      <p>First name valid: {{ first.valid }}</p>
      <p>Form value: {{ f.value | json }}</p>
      <p>Form valid: {{ f.valid }}</p>
    </div>

    <div [hidden]="!f.valid">
      <p>{{submitMessage }}</p>
    </div>
  `
,
})
export class SimpleFormComp {
  submitMessage = '';
  onSubmit(f: NgForm) {
    console.log(f.value);
    console.log(f.valid);
    this.submitMessage = '数据已提交';
  }
}
复制代码

页面测试:

设置更新选项

自 Angular5 以后,增长了这么一个新特性:updateOn blur或submit

表单字段或整个表单新增了选项 updateOn,它可让 Angular 仅在 blur 或 submit 事件时检查有效性,而不是默认的变动事件,这有助于提升性能。

例如,给定一个模板驱动的表单,以下所示:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
     <form #newUserForm="ngForm" (ngSubmit)="onSubmit(newUserForm)">

      <label for="user-name">User Name:</label>
      <input type="text" placeholder="User name"
             required maxlength="25" id="user-name"
             [(ngModel)]="userName" name="userName">

      <button type="submit" [disabled]="!newUserForm.form.valid">
        Register
      </button>
    </form>
  `
,
})
export class SimpleFormComp {
  onSubmit(f: NgForm) {
    console.log(f.value);  // { first: '', last: '' }
    console.log(f.valid);  // false
  }
}
复制代码

页面测试:

注意观察 html 代码中的 button 标签,当开始在输入框输入内容时,button 标签的 disabled 属性马上消失,通俗点讲就是表单时刻都在作有效性检查。

若是你如今想输入内容,让 Angular 仅在输入触发 blur 事件时才进行有效性检查:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
     <form #newUserForm="ngForm" (ngSubmit)="onSubmit(newUserForm)">

      <label for="user-name">User Name:</label>

      <input type="text" placeholder="User name"
          required maxlength="5" id="user-name"
          [(ngModel)]="userName" name="userName"
          [ngModelOptions]="{updateOn: 'blur'}" />

      <button type="submit" [disabled]="!newUserForm.form.valid">
        Register
      </button>
    </form>
  `
,
})
export class SimpleFormComp {
  onSubmit(f: NgForm) {
    console.log(f.value);  // { first: '', last: '' }
    console.log(f.valid);  // false
  }
}
复制代码

页面测试:

当输入完数据以后,鼠标焦点事件改变以后,button 标签才会启用。

对于上述对 input 标签的修改,也能够一次性对整个表单应用。

<form #newUserForm="ngForm"
      (ngSubmit)="onSubmit(newUserForm)"
      [ngFormOptions]="{updateOn: 'blur'}">

  ...
</form>
复制代码

NgForm与NgModel

NgForm 中关于 NgModel 的使用有三种用法,分为 ngModel、[ngModel]和[(ngModel)]。

ngModel

若是单独使用 ngModel,且没有为其赋值的话,它会在其所在的 ngForm.value 对象上添加一个 property,此 property 的 key 值为 ngModel 所在组件设置的 name 属性的值:

<form #f="ngForm">
  <input type="text" ngModel name="firstField">
  <br>
  <span>{{ f.controls['firstField']?.value }}</span>
  <p>{{f.value | json }}</p>    //{ "firstField": "" }
</form>
复制代码

单独使用 ngModel 时,若是没有为 ngModel 赋值的话,则必须存在 name 属性

[ngModel]

ngForm 中绑定的 property 的 key 为 ngModel 所在组件设置的 name 属性的值,value 值咱们能够赋予默认值。此时须要使用单向数据绑定的格式了,也就是[ngModel]:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
    <form #ff="ngForm">
      <input type="text" name="firstField" [ngModel]="model.firstField" placeholder='Input your userName' >
      <p>{{ff.value | json }}</p>
      <p>{{model | json}}</p>
    </form>
  `
,
})
export class SimpleFormComp {
    model = {
    firstField'hresh'
  };
}
复制代码

页面测试:

这里咱们使用了单向数据绑定的特色,能够为 ngForm.value 添加一个带有初始值的 property。

[(ngModel)]

上述的单向数据绑定在单纯地提供初始值颇有用,不过老是有些场景须要将用户输入体如今咱们的 model 上,此时就须要双向数据绑定了,也即[(ngModel)]:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
    <form #ff="ngForm">
      <input type="text" name="firstField" [(ngModel)]="model.firstField" placeholder='Input your userName' >
      <p>{{ff.value | json }}</p>
      <p>{{model | json}}</p>
    </form>
  `
,
})
export class SimpleFormComp {
    model = {
    firstField'hresh'
  };
}
复制代码

页面测试:

这里咱们不只为 ngForm.value 添加了一个带有初始值的 property,还能实现 Model 和 View 层的联动。

参考文献

Angular 2 ngForm中的ngModel、[ngModel]和[(ngModel)]

[译]Angular 5:升级和新功能的总结

相关文章
相关标签/搜索