app.module.ts 导入 FormsModule 

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';

import { AppComponent }  from './app.component';
import { HeroFormComponent } from './hero-form.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule
  ],
  declarations: [
    AppComponent,
    HeroFormComponent
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

如果某个组件、指令或管道是属于imports中所导入的某个模块的,那就不能再把它再声明到本模块的declarations数组中。 如果它是你自己写的,并且确实属于当前模块,才应该把它声明在declarations数组中。

containerform-groupform-controlbtn类来自 Twitter Bootstrap。纯粹是装饰。 我们使用 Bootstrap 来美化表单。

Angular 不需要containerform-groupform-controlbtn类, 或者外部库的任何样式。Angular 应用可以使用任何 CSS 库…… ,或者啥都不用

<form #heroForm="ngForm">
<div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"> </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="alterEgo" [(ngModel)]="model.alterEgo" name="alterEgo"> </div> <div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" required [(ngModel)]="model.power" name="power"> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> </div>

  

NgForm:

什么是NgForm指令? 但我们明明没有添加过NgForm指令啊!

Angular替你做了。Angular会在<form>标签上自动创建并附加一个NgForm指令。

NgForm指令为form增补了一些额外特性。 它会控制那些带有ngModel指令和name属性的元素,监听他们的属性(包括其有效性)。 它还有自己的valid属性,这个属性只有在它包含的每个控件都有效时才是真

<input>标签还添加了name属性 (attribute),并设置为 "name",表示英雄的名字。 使用任何唯一的值都可以。

当在表单中使用[(ngModel)]时,必须要定义name属性。

内部,Angular 创建了一些FormControl,并把它们注册到NgForm指令,再将该指令附加到<form>标签。 注册每个FormControl时,使用name属性值作为键值

  • 每个 input 元素都有id属性,label元素的for属性用它来匹配到对应的输入控件。

  • 每个 input 元素都有name属性,Angular 表单用它注册控件。

通过 ngModel 跟踪修改状态与有效性验证

ngModel可以获得比仅使用双向数据绑定更多的控制权。它还会告诉我们很多信息:用户碰过此控件吗?它的值变化了吗?数据变得无效了吗?

NgModel 指令不仅仅跟踪状态。它还使用特定的 Angular CSS 类来更新控件,以反映当前状态。 可以利用这些 CSS 类来修改控件的外观,显示或隐藏消息。

状态

为真时的 CSS 类

为假时的 CSS 类

控件被访问过。

ng-touched ng-untouched

控件的值变化了。

ng-dirty ng-pristine

控件的值有效。

ng-valid ng-invalid

例子:往姓名<input>标签上添加名叫 spy 的临时模板引用变量, 然后用这个 spy 来显示它上面的所有 CSS 类

<input type="text" class="form-control" id="name"
  required
  [(ngModel)]="model.name" name="name"
  #spy>
<br>TODO: remove this: {{spy.className}}
  • 查看输入框,但别碰它:  
  • 点击输入框,然后点击输入框外面。: 
  • 在名字的末尾添加些斜杠。
  • 删除名字。

(ng-valid | ng-invalid)这一对是我们最感兴趣的。当数据变得无效时,我们希望发出强力的视觉信号, 还想要标记出必填字段。可以通过加入自定义 CSS 来提供视觉反馈

输入框的左侧添加带颜色的竖条,用于标记必填字段和无效输入

添加两个样式来实现这一效果

.ng-valid[required], .ng-valid.required  {
  border-left: 5px solid #42A948; /* green */
}

.ng-invalid:not(form)  {
  border-left: 5px solid #a94442; /* red */
}

  

显示和隐藏验证错误信息

//template<label for="name">Name</label>
<input type="text" class="form-control" id="name"
       required
       [(ngModel)]="model.name" name="name"
       #name="ngModel">
<div [hidden]="name.valid || name.pristine" class="alert alert-danger">
  Name is required
</div><button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>

//tsnewHero() { this.model = new Hero(42, '', ''); }

 

当控件是有效的 (valid) 全新的 (pristine) 时,隐藏消息。 “全新的”意味着从它被显示在表单中开始,用户还从未修改过它的值。

input 创建了名叫name的变量,并且赋值为 "ngModel"( 指令的 exportAs 属性告诉 Angular 如何链接模板引用变量到指令。 这里把name设置为ngModel是因为ngModel指令的exportAs属性设置成了 “ngModel”)

点击 New Hero 按钮,表单被清空了。 输入框左侧的必填项竖条是红色的.

问题:

输入名字,再次点击 New Hero 按钮。 这次,出现了错误信息!为什么?我们不希望显示新(空)的英雄时,出现错误信息。

使用浏览器工具审查这个元素就会发现,这个 name 输入框并不是全新的。 表单记得我们在点击 New Hero 前输入的名字。 更换了英雄并不会重置控件的“全新”状态

我们必须清除所有标记,在调用 newHero() 方法后调用表单的 reset() 方法即可  (click)="newHero(); heroForm.reset()"

提交表单

<form (ngSubmit)="onSubmit()" #heroForm="ngForm">

<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>

切换两个表单区域(额外的奖励)

把表单包裹进<div>中,再把它的hidden属性绑定到HeroFormComponent.submitted属性。

<div [hidden]="submitted">
  <h1>Hero Form</h1>
  <form (ngSubmit)="onSubmit()" #heroForm="ngForm">

  </form>
</div>

开始就是可见的,因为submitted属性是 false,直到提交了这个表单。

submitted = false;

onSubmit() { this.submitted = true; }

当点击 Submit 按钮时,submitted标志会变成 true,并且表单像预想中一样消失了

当表单处于已提交状态时,需要显示一些别的东西。 在刚刚写的<div>包装下方,添加下列 HTML 语句:

<div [hidden]="!submitted">
  <div class="row">
    <div class="col-xs-3">Name</div>
    <div class="col-xs-9  pull-left">{{ model.name }}</div>
  </div>
  <button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>

当点Edit按钮时,这个只读块消失了,可编辑的表单重新出现了

angular2-模板驱动表单的更多相关文章

  1. Angular 表单(二) - 模板驱动表单

    import { Component, OnInit } from '@angular/core'; import { Hero} from '../hero'; @Component({ selec ...

  2. Angular2响应式表单

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

  3. Angular2响应式表单-翻译与概括官网REACTIVE FORMS页面

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

  4. Angular使用总结 --- 模版驱动表单

    表单的重要性就不多说了,Angular支持表单的双向数据绑定,校验,状态管理等,总结下. 获取用户输入 <div class="container-fluid login-page&q ...

  5. Angular使用总结 ---以密码确认为例实现模版驱动表单的自定义校验

    上一篇 总结了模版驱动表单的基本用法,示例中的校验使用的是原生HTML5的校验方式,本文补上自定义校验的部分. HTML5原生的表单校验属性(必填,长度限制,取值间隔,正则表达式等等)可以满足普通的校 ...

  6. Flask之模板web表单

    3.3 Web表单: web表单是web应用程序的基本功能. 它是HTML页面中负责数据采集的部件.表单有三个部分组成:表单标签.表单域.表单按钮.表单允许用户输入数据,负责HTML页面数据采集,通过 ...

  7. Django 构建模板form表单的两种方法

    通常情况下,我们想构建一张表单时会在模板文件login.html中写入 <form action="/your-name/" method="post"& ...

  8. 实验2、Flask模板、表单、视图和重定向示例

    实验内容 1. 实验内容 表单功能与页面跳转功 能是Web应用程序的基础功能,学习并使用他们能够更好的完善应用程序的功能.Flask使用了名为Jinja2的模板引擎,该引擎根据用户的交互级别显示应用程 ...

  9. layui模板注册表单

    今天晚上用layui模板做了一个简单的注册表单,功能主要有可以js验证密码重复,可以验证手机号码. 这是界面 下面是我的html文件代码 <!DOCTYPE html> <html ...

随机推荐

  1. Python3之XML模块

    一.简介 xml是实现不同语言或程序之间进行数据交换的协议,可扩展标记语言,标准通用标记语言的子集.是一种用于标记电子文件使其具有结构性的标记语言.xml格式如下,是通过<>节点来区别数据 ...

  2. Apache 配置 虚拟主机

    <VirtualHost *:80> ServerName tongcheng.5q88.cn:80 ServerAlias DirectoryIndex index.html index ...

  3. C++_异常8-异常、类和基础

    异常.类和继承以三种方式相互关联. 首先,可以像标准C++库所做的那样,从一个异常类派生出另一个. 其次,可以在类定义中嵌套异常类声明来组合异常. 第三,这种嵌套声明本身可以被继承,还可以作为基类. ...

  4. 基于中间件的RBAC权限控制

    RBAC 是什么 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联. 在 Django 中,权限就是用户对一个包含正则表达式 url ...

  5. ABP中文网入门篇教程中的一个bug

    入门--从空项目开始--使用ASP.NET Core Web Application https://cn.abp.io/documents/abp/latest/Autofac-Integratio ...

  6. Highcharts的一些属性

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. hdu1702 ACboy needs your help again!(栈处理)

    ACboy needs your help again! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  8. 微信小程序实现图片上传功能

    前端: 微信开发者工具 后端:.Net 服务器:阿里云 这里介绍微信小程序如何实现上传图片到自己的服务器上 前端代码 data: { productInfo: {} }, //添加Banner bin ...

  9. PIE SDK专题制图下地图的的操作

    1.    功能简介 制图模式和地图模式下用的地图是同一份地图,那么在制图模式下如果需要对地图进行操作(例如地图的拉框放大,缩小),那么该如何操作呢,地图范围视图变化在制图模式下该如何监听呢,下面主要 ...

  10. PIE SDK图层树右键菜单与命令绑定

    1.   功能简介 上一节已经介绍过图层树如何和地图和制图关联,图层树右键菜单主要是基于TocControl控件进行对菜单节点进行控制,TocControl主要作用是显示当前加载的图层有哪些.采用什么 ...