天天看點

Angular 2 表單

本章節我們将為大家介紹如何使用元件和模闆建構一個 Angular 表單。

利用 Angular 模闆,我們可以建立各種類型表單,例如:登入表單,聯系人表單,商品詳情表單等,而且我們也為這些表單的字段添加資料校驗。

接下來我們一步步來實作表單的功能。

導入初始化項目。

完整的項目建立可以參考:Angular 2 TypeScript 環境配置

或者直接下載下傳源代碼:點我下載下傳

解壓後,修改目錄名為angular-forms,修改 angular-forms/package.json 檔案中的 <b>"name": "angular-quickstart"</b> 為 <b>"name": "angular-forms"</b>。

完成後,我們執行 <b>cnpm install</b> 來載入依賴包。

以下建立了一個簡單的模型類 Site,包含了三個必需字段:id,name,url,一個可選字段:alexa。

在 angular-forms/app 目錄下建立 site.ts 檔案,代碼如下:

export class Site {

constructor(

public id: number,

public name: string,

public url: string,

public alexa?: number

) { }

}

以下代碼中,标為 public 的為公有字段,alexa 後添加一個問号(?)表示可選字段。

每個 Angular 表單分為兩部分:一個基于 HTML 的模闆,和一個基于代碼的元件,它用來處理資料和使用者互動。

在 angular-forms/app 目錄下建立 site-form.component.ts 檔案,代碼如下:

import { Component } from '@angular/core';

import { Site } from './site';

@Component({

moduleId: module.id,

selector: 'site-form',

templateUrl: 'site-form.component.html'

})

export class SiteFormComponent {

urls = ['www.runoob.com', 'www.google.com',

'www.taobao.com', 'www.facebook.com'];

model = new Site(1, '菜鳥教程', this.urls[0], 10000);

submitted = false;

onSubmit() { this.submitted = true; }

// TODO: 完成後移除

get diagnostic() { return JSON.stringify(this.model); }

執行個體中導入了 Component 裝飾器和 Site 模型。

@Component 選擇器 "site-form" 表示我們可以通過一個 <b>&lt;site-form&gt;</b> 标簽,把此表單扔進父模闆中。

templateUrl 屬性指向一個獨立的HTML模闆檔案,名叫 site-form.component.html。

diagnostic 屬性用于傳回這個模型的JSON形式。

修改 app.module.ts 來定義應用的根子產品,子產品中指定了引用到的外部及聲明屬于本子產品中的元件,比如 SiteFormComponent。

因為模闆驅動的表單有它們自己的子產品,是以我們得把 FormsModule 添加到本應用的 imports 數組中,這樣我們才能使用表單。

app/app.module.ts 檔案代碼如下

import { NgModule } from '@angular/core';

import { BrowserModule } from '@angular/platform-browser';

import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

import { SiteFormComponent } from './site-form.component';

@NgModule({

imports: [

BrowserModule,

FormsModule

],

declarations: [

AppComponent,

SiteFormComponent

bootstrap: [ AppComponent ]

export class AppModule { }

修改根元件檔案 app.component.ts,将 SiteFormComponent 放在其中。

selector: 'my-app',

template: '&lt;site-form&gt;&lt;/site-form&gt;'

export class AppComponent { }

建立模闆檔案 site-form.component.html ,代碼如下所示:

&lt;div class="container"&gt;

&lt;h1&gt;網站表單&lt;/h1&gt;

&lt;form&gt;

&lt;div class="form-group"&gt;

&lt;label for="name"&gt;網站名&lt;/label&gt;

&lt;input type="text" class="form-control" id="name" required&gt;

&lt;/div&gt;

&lt;label for="alexa"&gt;alexa 排名&lt;/label&gt;

&lt;input type="text" class="form-control" id="alexa"&gt;

&lt;button type="submit" class="btn btn-default"&gt;送出&lt;/button&gt;

&lt;/form&gt;

required 屬性設定的該字段為必需字段,如果沒有設定則是可選。

在 angular-forms 目錄下輸入以下指令:

打開 index.html 檔案,把以下樣式連結添加到 &lt;head&gt; 中:

&lt;link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css"&gt;

執行 <b>npm start</b> 後,通路:http://localhost:3000/,輸出效果如下:

Angular 2 表單

接下來我們使用 ngModel 進行雙向資料綁定,通過監聽 DOM 事件,來實作更新元件的屬性。

修改 app/site-form.component.html ,使用 ngModel 把我們的表單綁定到模型。代碼如下所示:

{{diagnostic}}

&lt;input type="text" class="form-control" id="name"

required

[(ngModel)]="model.name" name="name"&gt;

&lt;input type="text" class="form-control" id="alexa"

[(ngModel)]="model.alexa" name="alexa"&gt;

&lt;label for="url"&gt;網站 URL &lt;/label&gt;

&lt;select class="form-control" id="url"

[(ngModel)]="model.url" name="url"&gt;

&lt;option *ngFor="let p of urls" [value]="p"&gt;{{p}}&lt;/option&gt;

&lt;/select&gt;

每一個 input 元素都有一個 id 屬性,它被 label 元素的 for 屬性用來把标簽比對到對應的 input 。

每一個 input 元素都有一個 name 屬性, Angular 的表單子產品需要使用它為表單注冊控制器。

運作以上執行個體輸出結果如下:

Angular 2 表單

<b>{{diagnostic}} </b> 隻是用于測試時候輸出資料使用。

我們還可以通過 ngModel 跟蹤修改狀态與有效性驗證,它使用了三個 CSS 類來更新控件,以便反映目前狀态。

狀态

為 true 時的類

為 false 時的類

控件已經被通路過

<code>ng-touched</code>

<code>ng-untouched</code>

控件值已經變化

<code>ng-dirty</code>

<code>ng-pristine</code>

控件值是有效的

<code>ng-valid</code>

<code>ng-invalid</code>

這樣我們就可以添加自定義 CSS 來反應表單的狀态。

在 angular-forms 目錄下建立 forms.css 檔案,代碼如下:

.ng-valid[required], .ng-valid.required {

border-left: 5px solid #42A948; /* green */

.ng-invalid:not(form) {

border-left: 5px solid #a94442; /* red */

&lt;link rel="stylesheet" href="forms.css"&gt;

修改 app/site-form.component.html ,代碼如下所示:

[(ngModel)]="model.name" name="name"

#name="ngModel" &gt;

&lt;div [hidden]="name.valid || name.pristine"

class="alert alert-danger"&gt;

網站名是必需的

模闆中通過把 div 元素的 hidden 屬性綁定到 name 控件的屬性,我們就可以控制"name"字段錯誤資訊的可見性了。

删除掉 name 字段的資料,顯示結果如下所示:

Angular 2 表單

接下來我們建立一個用于添加網站的表單,在 app/site-form.component.html 添加一個按鈕:

&lt;button type="button" class="btn btn-default" (click)="newSite()"&gt;添加網站&lt;/button&gt;

将以上按鈕事件綁定到元件方法上:

active = true;

newSite() {

this.model = new Site(5, '', '');

this.active = false;

setTimeout(() =&gt; this.active = true, 0);

我們給元件添加一個 active 标記,把它初始化為 true 。當我們添加一個新的網站時,它把 active 标記設定為 false , 然後通過一個快速的 setTimeout 函數迅速把它設定回 true 。

我們可以使用 Angular 的指令 NgSubmit 來送出表單, 并且通過事件綁定機制把它綁定到 SiteFormComponent.submit() 方法上。

&lt;form *ngIf="active" (ngSubmit)="onSubmit()" #siteForm="ngForm"&gt;

我們定義了一個模闆引用變量 #siteForm ,并且把它初始化為 "ngForm" 。

這個 siteForm 變量現在引用的是 NgForm 指令,它代表的是表單的整體。

site-form.component.ts 檔案完整代碼如下:

app/site-form.component.html 完整代碼如下:

&lt;div [hidden]="submitted"&gt;

&lt;button type="submit" class="btn btn-default" [disabled]="!siteForm.form.valid"&gt;送出&lt;/button&gt;

&lt;button type="button" class="btn btn-default" (click)="newSite()"&gt;新增網站&lt;/button&gt;

&lt;div [hidden]="!submitted"&gt;

&lt;h2&gt;你送出的資訊如下:&lt;/h2&gt;

&lt;div class="row"&gt;

&lt;div class="col-xs-3"&gt;網站名&lt;/div&gt;

&lt;div class="col-xs-9 pull-left"&gt;{{ model.name }}&lt;/div&gt;

&lt;div class="col-xs-3"&gt;網站 alexa 排名&lt;/div&gt;

&lt;div class="col-xs-9 pull-left"&gt;{{ model.alexa }}&lt;/div&gt;

&lt;div class="col-xs-3"&gt;網站 URL &lt;/div&gt;

&lt;div class="col-xs-9 pull-left"&gt;{{ model.url }}&lt;/div&gt;

&lt;br&gt;

&lt;button class="btn btn-default" (click)="submitted=false"&gt;編輯&lt;/button&gt;

模闆中我們把 hidden 屬性綁定到 SiteFormComponent.submitted 屬性上。

主表單從一開始就是可見的,因為 submitted 屬性是 false ,當我們送出了這個表單則隐藏,submitted 屬性是 true:

最終的目錄結構為:

Angular 2 表單

本文所使用的源碼可以通過以下方式下載下傳,不包含 node_modules 和 typings 目錄。

源代碼下載下傳

完整執行個體示範 GIf 如下:

Angular 2 表單
下一篇: NPM 使用介紹