四,angular2 for javascript 开发指南-表单
流程
参照官网angular2 for typescript 表单的开发流程来进行
-
创建
Hero
模型类 -
创建控制此表单的组件
-
创建具有初始表单布局的模板
-
使用
ngModel
双向数据绑定语法把数据属性绑定到每个表单输入控件 -
往每个表单输入控件上添加
name
属性 (attribute) -
添加自定义 CSS 来提供视觉反馈
-
显示和隐藏有效性验证的错误信息
-
使用 ngSubmit 处理表单提交
-
禁用此表单的提交按钮,直到表单变为有效
搭建
按照搭建本地开发环境的说明,创建一个名为angular-forms
的新项目。
创建 Hero 模型类
官网对应的typescript版本是这样:创建hero.ts文件,内容如下,然后在hero-form.component.ts中使用
import { Hero } from './hero';
执行导入
export class Hero { constructor( public id: number, public name: string, public power: string, public alterEgo?: string ) { } }
但我们知道在javascript中无法直接使用class 创建类 ,所以使用<<三,angular2 for javascript 类 替代方案>>中提到的类替代方案,在angular-forms/app/app.component.js中创建对象Hero.如下所示:
Hero:function(id,name,power,alertEgo){ this.id = id; this.name = name; this.power = power; this.alertEgo = alertEgo; return this; }
创建表单组件
参照官网创建独立的表单组件,启动后,运行不成功,提示是module.id导致的错误,由于目前还没有找到对应的解决办法,所以这里将表单组件与app.commment.js根组件进行了合并.
app.comment.js内容如下:
(function(app) { app.AppComponent = ng.core.Component({ selector: 'my-app', templateUrl: 'hero-form.component.html' }) .Class({ constructor: function() { this.powers = ['Really Smart', 'Super Flexible','Super Hot', 'Weather Changer']; this.model = new this.Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet'); this.submitted = false; }, Hero:function(id,name,power,alertEgo){ this.id = id; this.name = name; this.power = power; this.alertEgo = alertEgo; return this; }, onSubmit:function(){ this.submitted = true; }, newHero:function(){ this.model = new this.Hero(42, '', ''); } }); })(window.app || (window.app = {}));
表单布局的模板文件
路径:angular-forms/hero-form.component.html
<div class="container"> <div [hidden]="submitted"> <h1>Hero Form</h1> <form (ngSubmit)="onSubmit()" #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" #name="ngModel"> <div [hidden]="name.valid || name.pristine" class="alert alert-danger">Name is required</div> </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> <button type="submit" class="btn btn-default" [disabled]="!heroForm.form.valid">Submit</button> </form> </div> <div [hidden]="!submitted"> <h2>You submitted the following:</h2> <div class="row"> <div class="col-xs-3">Name</div> <div class="col-xs-9 pull-left">{{ model.name }}</div> </div> <div class="row"> <div class="col-xs-3">Alter Ego</div> <div class="col-xs-9 pull-left">{{ model.alterEgo }}</div> </div> <div class="row"> <div class="col-xs-3">Power</div> <div class="col-xs-9 pull-left">{{ model.power }}</div> </div> <br> <button class="btn btn-default" (click)="submitted=false">Edit</button> </div> <button type="button" class="btn btn-default" (click)="newHero();heroForm.reset()">New Hero</button> </div>
修改 app.module.ts
导入FormsModule,在imports数组中添加:ng.forms.FormsModule,导入添加ng模块的方法目前并没有找到一个标准的方法,这里是通过测试发现的,将
ng.forms.FormsModule
分为三部分,(1)ng为固定用法,在index.htm头部引入对应模型的js文件之后,即可在
imports
中导入对应的模型对象,(2)中间
与引用的ng模型文件名保持一致,这里forms
为forms.umd.js,其中引用的ng模型文件名
是ng模型文件的后缀说明,所以中间为forms.(3).umd.js
FormsModule
的名称来源可查阅官网api文档,与其保持一致即可.
(function(app) { app.AppModule = ng.core.NgModule({ imports:[ ng.platformBrowser.BrowserModule, ng.forms.FormsModule ], //声明本模块中拥有的视图类 declarations:[app.AppComponent], bootstrap:[app.AppComponent] }) .Class({ constructor: function() {} }); })(window.app || (window.app = {}));
样式文件,以及ng模型的引入
index.html
<html> <head> <meta charset="utf-8"> <title>Angular 2 实例 - 烂笔头(bf361.com)</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="forms.css"> <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css"> <!-- 1. 载入库 --> <!-- IE 需要 polyfill --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/reflect-metadata/Reflect.js"></script> <script src="node_modules/rxjs/bundles/Rx.js"></script> <script src="node_modules/@angular/core/bundles/core.umd.js"></script> <script src="node_modules/@angular/common/bundles/common.umd.js"></script> <script src="node_modules/@angular/compiler/bundles/compiler.umd.js"></script> <script src="node_modules/@angular/platform-browser/bundles/platform-browser.umd.js"></script> <script src="node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"></script> <script src="node_modules/@angular/forms/bundles/forms.umd.js"></script> <!-- 2. 载入 'modules' --> <script src='app/app.component.js'></script> <script src='app/app.module.js'></script> <script src='app/main.js'></script> </head> <!-- 3. 显示应用 --> <body> <my-app>Loading...</my-app> </body> </html>
styles.css
h1 { color: #369; font-family: Arial, Helvetica, sans-serif; font-size: 250%; } body { margin: 2em; }
forms.css
.ng-valid[required], .ng-valid.required { border-left: 5px solid #42A948; /* green */ } .ng-invalid:not(form) { border-left: 5px solid #a94442; /* red */ }