From表单分为两种类型:

  • 模板驱动表单(Template-Driven Forms)
  • 模型驱动表单(Model-Driven-Forms)
    模型:有结构的状态(是一种数据结构)FormContrller 表单项

@angular/forms
模板驱动表单
@angular/reactiveForms

关注点是表单的行为,不是怎么生成DOM。关注点是出错了,是一种出错的状态,是否发生了改变。

Template-Driven Forms

  • 知识点1

Template 驱动表单时,因为模板驱动的表单有它自己的模块,所以我们得把FormsModule添加到应用的imports数组中去,这样我们才能使用表单。

注意:

如果一个组件、指令或者管道出现在模块的imports数组中,就说明它是外来模块不要在到declarations数组中声明它们。
如果你自己写的它,并且它属于当前模块,就要把它声明在declarations数组中。

  • 知识点2 - 表单
<div class="container">
  <h1>Hero Form</h1> {{diagnostic}} <form> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"> Todo:remove this: {{model.name}} </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="laterEgo" [(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 p of powers" [value]="p">{{p}}</option> </select> </div> </form> </div>
  • 每个 input 元素都有id属性,它被label元素的for属性用它来匹配到对应的输入控件input。?
  • 每个 input 元素都有name属性,Angular 表单用它注册控件。(用于做表单验证)
  • diagnostic 的显示是因为在组件中,使用了get diagnostic() { return JSON.stringify(this.model); }这段代码,这个在语法级别,是相当于diagnostic这个属性是只读的。(只读也可以使用readonly age: number;)
  • 知识点3 - [(ngModel)]内幕

    • [] ,这是一个从模型到视图的单项数据绑定。
    • () ,这是一个从视图到模型的反向数据绑定。
    • [()] ,这是双向数据绑定和双向数据流。
    • 我们可以把ngModel绑定拆成两个独立的绑定,就想我们重写的“Name”的<input>绑定一样:
    <input type="text" class="form-control" id="name" required [ngModel]="model.name" name="name" (ngModelChange)="model.name = $event" >
    Todo: remove this: {{model.name}}

    这个属性绑定看起来很眼熟,但事件绑定看起来有点怪。
    ngModelChange并不是<input> 元素的事件。 它实际上是来自NgModel指令的事件属性。 当 Angular 在表单中看到[(x)]的绑定目标时, 它会期待这个x指令有一个名为x的输入属性,和一个名为xChange的输出属性。

    模板表达式中的另一个古怪之处是model.name = $event
    。 之前看到的$event对象来自 DOM 事件。 但ngModelChange
    属性不会生成 DOM 事件 —— 它是Angular EventEmitter类型的属性,当它触发时, 它返回的是输入框的值 —— 也正是希望赋给模型name
    属性的值。

    很高兴知道这些,但是这样现实吗?实践上中,几乎总是优先使用[(ngModel)]形式的双向绑定。 只有当需要在事件处理函数中做一些特别的事情(例如合并或限制按键频率)时,才会拆分出独立的事件处理函数。

  • 知识点4 - 表单验证

    在表单中使用ngModel,能让我们比仅仅使用双向数据绑定获得更多的控制权。eg:

    • 用户是否碰过此控件?
    • 它值的变化?
    • 数据是否有效?

    ngModel指令不仅仅跟踪状态,它还使用三个CSS类来更新控件,以反映当前的状态。

状态 为真时的CSS类 为假时的CSS类
控件已经被访问过 ng-touched ng-untouched
控件值已经变化 ng-dirty ng-pristine
控件值是有效的 ng-valid ng-invalid

我们可以在name的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}} // 这样显示className
  • 知识点5 - 表单验证
<div class="form-group">
      <label for="name">Name</label>
      <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name" #spy="ngModel">
      Todo:remove this: {{model.name}}| {{spy.className}}
    </div>
    <div [hidden]="spy.valid || spy.pristine" class="alter alter-danger">
      Name IS required!
    </div>

#spy=”ngModel”可以得到这个input`的一些状态。

  • 知识点6 - 表单重置

    heroForm.reset()可以将表单重置。

  • 知识点7 - 表单提交

    在填表完成之后,用户还应该能提交这个表单。 “Submit(提交)”按钮位于表单的底部,它自己不做任何事,但因为有特殊的 type 值 (type=”submit”),所以会触发表单提交。

    表单提交,我们使用NgSubmit,并且通过事件绑定把它绑定到HeroFormComponent.submit()方法。

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

NgForm指令
什么NgForm指令?之前没有添加过 NgForm 指令啊!

是 Angular 干的。Angular 自动创建了NgForm指令,并把它附加到标签。NgForm指令为form元素扩充了额外的特性。 它持有通过ngModel指令和name属性为各个元素创建的那些控件,并且监视它们的属性变化,包括有效性。 它还有自己的valid属性,只有当其中所有控件都有效时,它才有效。

Model-Driven-Forms

有时候手动编写和维护表单所需工作量和时间会过大。特别是在需要编写大量表单时。表单都很相似,而且随着业务和监管需求的迅速变化,表单也要随之变化,这样维护的成本过高。

整个例子,我的理解就是:

所谓动态表单,也就是,将表单的配置信息写成配置方便更改,而不是以模板的形式写死,这样,我们就可以在不修改应用代码的情况下,动态的创建表单项。

程序启动

我们将使用响应式表单(Reactive Forms)。

响应式表单属于另外一个叫做ReactiveFormsModule的NgModule,所以,为了使用响应式表单类的指令,我们得往@angular/forms库中引入ReactiveFormsModule模块。并且需要引入imports: [ ReactiveFormsModule ],这一点很重要,不能忘记引入

自定义表单

自定义表单的例子
自定义表单验证的资料

模板驱动表单的实现例子

pdf文档的名字:Custom Form Controls in Angular 2 by thoughtram.pdf

下面是一个使用表单的例子。

import { Component,forwardRef } from '@angular/core';
import { ControlValueAccessor,NG_VALUE_ACCESSOR } from '@angular/forms';

// 所谓表单指的就是,数据从model-->view,然后再从view-->model的这样的一些项,类似的有`input`,`select`,`textarea`等这样的。
@Component({
  template: `
        <input type="text" [(ngModel)]="value">
    `,providers: [
    {
      provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(() => CustomerFormItemComponent),multi: true,},],})
class CustomerFormItemComponent implements ControlValueAccessor {
  private propagateChange: (_: any) => {};
  private _value: String; // 为了避免出现死循环,所以设置一个_value

  // 如果只设置get方法的话,可以设置只读
  get value() {
    return this._value;
  }
  // 这种写法是语法级别的,set方法可以很好的监听传入值的改变。
  set value(value: String) {
    if (this._value === value) {
      return;
    } else {
      this._value = value;
      this.propagateChange(value);
    }
  }
  // 表单初始化的时候,完成model --> view 的数据设置。
  writeValue(value: String): void {
    this._value = value;
  }

  registerOnChange(fn: any): void {
    this.propagateChange = fn;
  }

  registerOnTouched(fn: any): void {
  }
}

未完待续…

Angular2 之 Form 表单的更多相关文章

  1. HTML5新增form控件和表单属性实例代码详解

    这篇文章主要介绍了HTML5新增form控件和表单属性实例代码详解,需要的朋友可以参考下

  2. wordpress添加Html5的表单验证required方法小结

    这篇文章主要介绍了wordpress添加Html5的表单验证required方法小结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5表单验证特性(知识点小结)

    这篇文章主要介绍了HTML5表单验证特性的一些知识点,本文通过实例代码截图的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. amazeui页面分析之登录页面的示例代码

    这篇文章主要介绍了amazeui页面分析之登录页面的示例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. ios – Swift Eureka Form中的循环

    我正在构建一个Eureka表单,并希望在表单中放置一个循环来构建基于数组的步进器列表.我试图使用的代码是:但是,当我这样做时,我在StepperRow行上出现了一个错误:所以看起来Swift不再认为它在形式之内并且正在关注

  6. swift 上传图片和参数 upload image with params

    Alamofire.upload(urlRequest.0,urlRequest.1).progress{(bytesWritten,totalBytesWritten,totalBytesExpectedToWrite)inprintln("\(totalBytesWritten)/\(totalBytesExpectedToWrite)")}}

  7. swift – 使用PostgreSQL在Vapor 3中上传图片

    我正在关注这些家伙MartinLasek教程,现在我正在“图片上传”.似乎没有人能回答“如何上传iVapor3图像”的问题Db连接正常,所有其他值都保存.这是我的创建方法:和型号:}和叶子模板:我知道需要一种管理文件的方法和原始图像字节,但我怎么去那里?这使用多部分表单的自动解码:upload.leaf文件是:使用File类型可以访问上载文件的本地文件名以及文件数据.如果将其余的Question字段添加到ExampleUpload结构中,则可以使用该路径捕获整个表单的字段.

  8. Android Studio是否支持用于Android UI设计的AngularJS?

    我对AndroidStudio有疑问:AS在设计XML文件时是否支持AngularJS代码,例如:对于小动画或效果?

  9. android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2

    我正尝试使用Angularjs(使用IonicFramework)通过GoogleOAuth2从我的Phonegap应用程序登录.目前我正在使用http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html进行登录.但是当我使用Angular-UI-RouterforIonic时,它正在创建非常

  10. android – 有没有办法阻止Mobile Safari在HTML表单的数字字段中插入逗号?

    我有一个网站,其中包含一个表单,允许用户输入信用卡详细信息.卡号,发行号,CVC号和他们希望存入的金额的字段使用HTML形式的输入框,类型为“数字”.iOS5附带的更新的MobileSafari会自动在“数字”输入字段中将逗号插入数字中.这不仅在CC编号中看起来很愚蠢,而且会破坏我的验证.有办法阻止这个吗?

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部