四,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.jsFormsModule的名称来源可查阅官网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 */
}
最终效果



