Angular 4.x Template-Driven Forms
Angular 4.x 中有两种表单:
本文主要介绍 Template-Driven Forms (模板驱动式表单) ,将涉及 Contents
Form base and interfaceForm base<form novalidate> <label> <span>Full name</span> <input type="text" name="name" placeholder="Your full name"> </label> <div> <label> <span>Email address</span> <input type="email" name="email" placeholder="Your email address"> </label> <label> <span>Confirm address</span> <input type="email" name="confirm" placeholder="Confirm your email address"> </label> </div> <button type="submit">Sign up</button> </form> 接下来我们要实现的功能如下:
User interface// signup.interface.ts export interface User { name: string; account: { email: string; confirm: string; } } ngModule and template-driven forms在我们继续深入介绍 template-driven 表单前,我们必须在 import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ ...,FormsModule ],declarations: [...],bootstrap: [...] }) export class AppModule {}
Template-driven approach使用模板驱动的表单,我们基本上可以将组件类留空,直到我们需要读取/写入值 (例如提交和设置初始值)。我们将基于上面的定义的基础表单,创建 signup-form.component.ts import { Component } from '@angular/core'; @Component({ selector: 'signup-form',template: ` <form novalidate>...</form> ` }) export class SignupFormComponent { constructor() {} } 这是一个很基础的组件,接下来我们导入之前定义的 import { User } from './signup.interface'; @Component({...}) export class SignupFormComponent { public user: User = { name: '',account: { email: '',confirm: '' } }; } 初始化 SignupFormComponent 组件类中的用户模型后,我们开始实现第一个功能点:即绑定 name、email、confirm 输入框的值。 Binding ngForm and ngModel我们从 ngForm 开始,更新后的模板如下: <form novalidate #f="ngForm"> <label> <span>Full name</span> <input type="text" placeholder="Your full name"> </label> </form> 上面代码中,我们把
@Directive({ selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,[ngForm]',providers: [formDirectiveProvider],host: {'(submit)': 'onSubmit($event)','(reset)': 'onReset()'},outputs: ['ngSubmit'],exportAs: 'ngForm' }) export class NgForm extends ControlContainer implements Form {} 在模板中,我们可以通过以下方式查看表单的值: {{ f.value | json }} // {} 上面示例 ngModel,[ngModel] and [(ngModel)]在 Angular 4.x 中
<form novalidate #f="ngForm"> ... <input type="text" placeholder="Your full name" name="name" ngModel> ... </form>
运行以上代码,f.value 的输入值如下: {{ f.value | json }} // { name: '' } 非常好,我们已经绑定了 name 输入框的值。但我们应该怎么为输入框设置初始值?
为了设置输入框初始值,我们先要更新一下 SignupFormComponent 组件类的用户模型: ... user: User = { name: 'Semlinker',account: { email: '',confirm: '' } }; ... 更新完用户模型,我们需要同步更新组件模板,具体如下: <form #f="ngForm"> ... <input type="text" placeholder="Your full name" name="name" [ngModel]="user.name"> ... </form> 代码重新运行后,f.value 的输出如下: {{ f.value | json }} // { name: 'Semlinker' } 从上面示例可以看出,使用
如果想在 name 输入框值变化时,自动同步更新
<form #f="ngForm"> ... <input type="text" placeholder="Your full name" name="name" [(ngModel)]="user.name"> ... </form> 上面示例成功运行后,我们可以在模板中新增以下代码,然后观察 {{ user | json }} // { name: 'Semlinker' } 需要注意的是,以下两种方式是等价的: <input [(ngModel)]="user.name"> <input [ngModel]="user.name" (ngModelChange)="user.name = $event"> 其中 ngModels and ngModelGroup我们已经介绍了 <form novalidate #f="ngForm"> <label> <span>Full name</span> <input type="text" placeholder="Your full name" name="name" ngModel> </label> <div ngModelGroup="account"> <label> <span>Email address</span> <input type="email" placeholder="Your email address" name="email" ngModel> </label> <label> <span>Confirm address</span> <input type="email" placeholder="Confirm your email address" name="confirm" ngModel> </label> </div> <button type="submit">Sign up</button> </form> 使用 ngForm -> '#f' ngModel -> 'name' ngModelGroup -> 'account' -> ngModel -> 'email' -> ngModel -> 'confirm' 以上代码成功运行后,浏览器中页面显示的结果: // { name: 'Semlinker',account: { email: '',confirm: '' } } {{ f.value | json }} 此时我们已经完成了表单数据绑定,接下来我们来为表单增加提交逻辑。 Template-driven submitAngular 表单中提供了 <form novalidate (ngSubmit)="onSubmit(f)" #f="ngForm"> ... </form> 当用户提交表单时,我们将会把 export class SignupFormComponent { user: User = {...}; onSubmit({ value,valid }: { value: User,valid: boolean }) { console.log(value,valid); } } 上面代码中,我们使用 Template-driven error validation在为表单项添加验证规则前,我们先来更新一下 SignupFormComponent 组件中的 <form novalidate (ngSubmit)="onSubmit(f)" #f="ngForm"> ... <button type="submit" [disabled]="f.invalid">Sign up</button> </form> 以上代码我们通过 接下来开始进入正题,为表单添加验证规则: <form novalidate #f="ngForm"> <label> ... <input ... ngModel required> </label> <div ngModelGroup="account"> <label> ... <input ... name="email" ngModel required> </label> <label> ... <input ... name="confirm" ngModel required> </label> </div> <button type="submit">Sign up</button> </form> 上面代码中,我们为每个 input 表单控件,添加了
<form novalidate #f="ngForm"> {{ f.controls.name?.errors | json }} </form>
接下来为我们的 name 表单控件,添加显示异常信息的代码: <div *ngIf="f.controls.name?.required" class="error"> Name is required </div> 虽然我们已经可以获取某个表单项的验证信息,但有没有觉得使用 <label> ... <input ... #userName="ngModel" required> </label> <div *ngIf="userName.errors?.required" class="error"> Name is required </div> (备注:此处一定要使用 以上代码成功运行后,我们在浏览器中看到了异常信息,为了避免一开始就显示异常信息,我们可以更新一下 <div *ngIf="userName.errors?.required && userName.touched" class="error"> Name is required </div> 除了使用 <!-- name --> <div *ngIf="userName.errors?.required && userName.touched" class="error"> Name is required </div> <div *ngIf="userName.errors?.minlength && userName.touched" class="error"> Minimum of 2 characters </div> <!-- account: { email,confirm } --> <div *ngIf="userEmail.errors?.required && userEmail.touched" class="error"> Email is required </div> <div *ngIf="userConfirm.errors?.required && userConfirm.touched" class="error"> Confirming email is required </div> 我们通过使用模板变量的方式,为 account 表单组添加了显示验证异常信息的功能。但有没有其它更好的方式呢?有没有办法去掉 <div ngModelGroup="account" #userAccount="ngModelGroup"> <label> <span>Email address</span> <input type="email" placeholder="Your email address" name="email" ngModel required> </label> <label> <span>Confirm address</span> <input type="email" placeholder="Confirm your email address" name="confirm" ngModel required> </label> <div *ngIf="userAccount.invalid && userAccount.touched" class="error"> Both emails are required </div> </div> (备注:记得移除模板上的 我有话说表单控件的状态除了
|
- 利用resteasy框架构建rest webservice----第二波:使用不同
- Navicat for MySQL连接mysql数据库时提示错误:Can't c
- Getting Started with AngularJS 1.5 and ES6: part 6
- 什么是Unikernel?
- apt-get在公司代理后面的docker中
- angularjs – 有没有办法将类添加到组件根元素?
- 在Scala泛型语法中放置“forSome”子句有什么重要意义?
- loops – Angular 2无法在formArrays上找到带有未指定name属
- 什么是Bash的\u0026\u0026和||的等效PowerShell操作
- angularjs – typeahead angular ui – 无法读取undefined的