建立User模型類建立表單組件頁面測試總結參考文獻javascript
在 Angular知識學習(一)中有講述到表單的知識,不過那是最基礎的演示,在以後的學習中又瞭解到模板驅動表單,因此考慮對以前的表單案例進行重構,完善表單功能,讓案例更接近應用。css
根據官網模板驅動表單的知識內容,咱們從新構建人員登記表單,主要分爲如下步驟:html
ngModel
雙向數據綁定語法把數據屬性綁定到每一個表單輸入控件。name
屬性 (attribute)。使用 Angular CLI 命令 ng g class
生成一個名叫 Uuer
的新類: java
ng g class model/uuer
複製代碼
內容以下:nginx
export class Uuser {
constructor(
public name: string,
public sex: string,
public city: string,
public hobbies: any[],
public remark: string
) {
}
}
複製代碼
該類主要包含五個屬性,分別是姓名、性別、城市、愛好和備註。其中愛好有多個,因此用數組來表示。web
使用 Angular CLI 命令 ng g component
生成一個名叫 UserForm
的新組件: bootstrap
ng g component components/userForm
複製代碼
由於模板驅動的表單位於它們本身的模塊,因此在使用表單以前,須要將 FormsModule
添加到應用模塊的 imports
數組中。對 app.module.ts
進行修改:數組
import { FormsModule } from '@angular/forms';
imports: [
BrowserModule,
FormsModule
]
複製代碼
有兩處更改app
FormsModule
。FormsModule
添加到 ngModule
裝飾器的 imports
列表中,這樣應用就能訪問模板驅動表單的全部特性,包括 ngModel
。關於表單內容的分析,官方文檔寫的很是詳細,這裏我只針對本案例中的難點進行分析,其餘細節部分能夠閱讀官方文檔。框架
user-form.component.html
內容以下:
<h2>人員登記系統</h2>
<div class="container">
<div [hidden]="submitted">
<form (ngSubmit)="onSubmit()" #form="ngForm">
<div class="form-group">
<label for="name">姓 名</label>
<input class="form-control" id="name" type="text" required name="name" [(ngModel)]="user.name" #name="ngModel">
<span [hidden]="name.valid || name.pristine" class="alert alert-danger">Name is required</span>
</div>
<div class="form-group">
<label>性 別 </label>
<div class="radio-inline">
<input type="radio" value="男" name="sex" id="man" [(ngModel)]="user.sex" > <label for="man">男</label>
</div>
<div class="radio-inline">
<input type="radio" value="女" name="sex" id="woman" [(ngModel)]="user.sex" > <label for="woman">女</label>
</div>
</div>
<div class="form-group">
<label for="city">城 市</label>
<select class="form-control" id="city" required name="city" [(ngModel)]="user.city" #city="ngModel">
<option *ngFor="let ct of cities" [value]="ct">{{ct}}</option>
</select>
<span [hidden]="city.valid || city.pristine" class="alert alert-danger">City is required</span>
</div>
<div class="form-group">
<label for="hobby">愛 好</label>
<span *ngFor="let item of user.hobbies;let key=index" class="checkbox-inline">
<input type="checkbox" [id]="'check'+key" [(ngModel)]="item.status" [name]="'check'+key"><label [for]="'check'+key">{{item.title}}</label>
</span>
</div>
<div class="form-group">
<label for="remark">備 注</label>
<textarea class="form-control" id="remark" type="text" required name="remark" [(ngModel)]="user.remark" #remark="ngModel"></textarea>
<span [hidden]="remark.valid || remark.pristine" class="alert alert-danger">remark is required</span>
</div>
<button type="submit" class="btn btn-success" [disabled]="!form.valid">Submit</button>
<button type="button" class="btn btn-default" (click)="newUser();form.reset()">New User</button>
</form>
</div>
<div [hidden]="!submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">姓 名</div>
<div class="col-xs-9">{{ user.name }}</div>
</div>
<div class="row">
<div class="col-xs-3">性 別</div>
<div class="col-xs-9">{{ user.sex }}</div>
</div>
<div class="row">
<div class="col-xs-3">城 市</div>
<div class="col-xs-9">{{ user.city }}</div>
</div>
<div class="row">
<div class="col-xs-3">愛 好</div>
<div class="col-xs-9">
<span *ngFor="let item of user.hobbies">
<span *ngIf="item.status == 1">{{item.title}}</span>
</span>
</div>
</div>
<div class="row">
<div class="col-xs-3">備 注</div>
<div class="col-xs-9">{{ user.remark }}</div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>
</div>
複製代碼
同官方文檔中案例相比,本文的案例增長了單選框和多選框的應用,尤爲是多選框,考慮到數據的雙向綁定,因此必須對 user.hobbies
屬性進行初始化,經過勾選前臺按鈕,來改變 user.hobbies
的狀態值,從而達到信息記錄的目的。
user-form.component.ts
內容以下:
import { Component, OnInit } from '@angular/core';
import { Uuser } from '../../model/uuser';
@Component({
selector: 'app-user-form',
templateUrl: './user-form.component.html',
styleUrls: ['./user-form.component.css']
})
export class UserFormComponent implements OnInit {
submitted = false;
cities = ['北京', '上海', '廣州 ', '深圳', '杭州', '武漢', '成都'];
hobbies = ['唱歌', '跳舞', '跑步', '健身', '游泳'];
user = new Uuser('', '男', this.cities[1], [], '');
constructor() { }
ngOnInit(): void {
this.setHobbies();
}
//每一個User對象都初始化hobby屬性,只是status值默認爲0,經過前臺勾選來修改status
setHobbies() {
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < this.hobbies.length; i++) {
this.user.hobbies.push(
{
title: this.hobbies[i],
status: 0
}
);
}
}
onSubmit() {
this.submitted = true;
}
newUser() {
this.user = new Uuser('', '', '', [], '');
this.setHobbies();
}
}
複製代碼
爲了增長前臺表單的觀賞性,對錶單的 CSS 樣式作了一些修改。
首先是 styles.css
,引入 Bootstrap 樣式,對錶單總體框架顯示進行優化。
@import url('https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css');
複製代碼
其次是 user-form.component.css
h2{
text-align: center;
}
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
複製代碼
能夠在輸入框的左側添加帶顏色的豎條,當在必填字段輸入有效內容時,輸入框左側會變爲綠色,不然視爲無效,變爲紅色。
對上述的代碼進行驗證,首先完整走一遍邏輯過程。
咱們來梳理一下流程,首先是維護一我的的基本信息,點擊 Submit 按鈕提交表單,即跳轉到人員信息查看頁面,再點擊 Exit 按鈕退回到人員維護頁面,點擊 New User 按鈕,清空頁面內容,從新錄入人員信息,再次提交表單可正常跳轉到人員信息查看頁面。
測試過程當中能夠發現,當必填項不填寫內容,Submit 按鈕始終是灰色的,即沒法點擊提交,此處是對整個表單進行有效驗證,在實際應用中也是頗有必要的。
關於性別單選框有一點須要注意:平時咱們設置單選框的默認值,加上 checked 便可,可是因爲在當前案例中使用了雙向數據綁定,因此該屬性不起做用,必須給 user.sex 設置默認值,從而實現單選框的默認選定。
關於愛好多選框,從數據雙向綁定的角度來看,是沒法向 user.hobbies 中增長數據,多選框的勾選只是狀態值的改變,因此在 user-form.component.ts
文件中會增長一個 setHobbies
方法。
本文對於 Angular 表單的使用進行了優化,利用框架特性來支持數據修改、驗證和更多操做:
@Component
裝飾器的表單組件類。NgForm.ngSubmit
事件屬性來處理表單提交。#form
和 #name
。[(ngModel)]
語法用來實現雙向數據綁定。name
屬性的用途是有效性驗證和對錶單元素的變動進行追蹤。valid
屬性,可用於檢查控件是否有效、是否顯示/隱藏錯誤信息。NgForm
的有效性狀態,控制 Submit 按鈕的禁用狀態。