Angular Forms
for template-driven forms
非常好的入門課程 重點只放在template-driven forms
會用到
Rxjs
https://putsreq.com/
如果不太懂的話 可以先看
Angular: Getting Started
會有Angular 各方面都有講到一點
app.module.ts
import { FormsModule } from '@angular/forms';
imports: FormsModule
加入 FormsModule
用CLI 產生 ng g c user-settings-form
app.component.html 移除內容 加上 <app-user-settings-form></app-user-settings-form>
npm install --save bootstrap
angular.json 加入 "styles": "node_modules/bootstrap/dist/css/bootstrap.min.css"
要重開ng serve 才會吃到 新的 styles
卡關記錄 一直沒有bootstrap樣式
因為 我放到 test 那層去了 請放到 architect > build > options > styles 才是正確路徑
補充 要改port 放在 architect > serve > options > "port": 4500
放到github git remote add origin "Clone with HTTPS 的網址"
https://angular.tw/api/forms/NgForm
Using NgForm
<form #form="ngForm"> 最下面加上 {{form | json}} 可以看到form的資訊
NgModel
input 加上 ngModel 後 {{form.value | json}} 會有變化 => 要有 name 才會有改變
Creating a Data Model
建立 interface UserSettings 這樣就可以在 設定時 用Ctrl+空白鍵 得到提示
export interface UserSettings {
name: string,
emailOffers: boolean,
}
userSettings:UserSettings ={
name: 'Milton',
emailOffers: true
}
Two-way Data Binding
input 改成 [(ngModel)] = "userSettings.name" 這樣變成雙向綁定
{{userSettings | json}} 會變成 頁面一載入 就會有值 修改內容值也會改變
Copying Form Data
紀錄原本資料 可以用 userSettings : UserSettings = { ...this.originalUserSettings };
3個點是淺複製 要深複製需要另外處理(Lodash)
{{originalUserSettings | json}} 觀察改變input內容 這裡就不會變了
HTML5 Field Validation
預設關掉 加上 <form #form="ngForm" ngNativeValidate> 可以打開
HTML5驗證範例 <input id="name" name="name" class="form-control" [(ngModel)] = "userSettings.name" required pattern="B.*" minlength="3" maxlength="4" />
CSS Classes for Validation
可以在 input 加上 #classTest 跟 {{ classTest.className }} 來觀察變化
ng-untouched : 預設
ng-touched : 取得焦點 離開後
ng-pristine : 預設
ng-dirty : 內容修改過 有改過再改回來一樣的 還是dirty
ng-valid : 驗證通過
ng-invalid : 驗證沒有通過
NgModel Properties for Validation
可以在 input 加上 #classTest="ngModel" 跟 {{ classTest.untouched}} 來觀察變化
Styling Forms with Validation Errors
建立一個css 叫.field-error 就可以在input 加入 [class.field-error]="form.submitted && nameField.invalid"
表示當是true時 class 就會加入field-error , 當改成false 就移除field-error 也就是 當form有submit過 和 nameField驗證沒過 就加入field-error
<div [hidden]="!form.submitted || nameField.valid" > 也是一樣 ( 錯誤訊息 )
當是ture時 div 就會hidden , 當是false 就會顯示 也就是 還沒有submit前 或 驗證通過 一律隱藏
Submitting Forms
<form #form="ngForm" (ngSubmit)="onSubmit(form)">
表示當form submit時會去呼叫user-settings-form.component.ts的onSubmit方法 onSubmit(form: NgForm) {}
Handling Form Control Events
<input (blur)="onBlur(nameField)">
表示當input 觸發blur 時會去呼叫user-settings-form.component.ts的onBlur方法 onBlur(field : NgModel) {}
Creating a Data Service
用CLI 產生 service -> ng g s data
Form Posting Using Observables
用Rxjs模擬API
新增 postUserSettingsForm(userSettings: UserSettings) : Observable<UserSettings> , return of(userSettings);
this.dataService.postUserSettingsForm(this.userSettings).subscribe(
result => console.log('success',result),
error=>console.log('error',error)
)
HTTP Access Using HttpClient
加入 HttpClientModule
app.module.ts
import { HttpClientModule } from '@angular/common/http';
imports: HttpClientModule
修改 postUserSettingsForm
return this.http.post('測試用URL', userSettings);
Posting a Form
https://putsreq.com/ 建立一個測試用URL
var body = JSON.parse(request.body);
body.id="168";
response.body = body;
Handling POST Errors
https://putsreq.com/ 測試用URL改成
response.status = 400;
response.body = { errorMessage:'API Fail!' };
加上檢查前端驗證成功再送出,加入postError , postErrorMessage 控制錯誤訊息
onSubmit(form: NgForm) {
if (form.valid) { /*移除沒有改的code*/ error => this.onHttpError(error));}
else {this.postError = true; this.postErrorMessage = "Please fix the above errors"; }
}
onHttpError(errorResponse: any) {
this.postError = true; this.postErrorMessage = errorResponse.error.errorMessage;
}
//HTML
<div [hidden]="!postError" class="alert alert-danger">
{{ postErrorMessage }}
</div>
Retrieving Data for Select Elements
將下拉選單 也用service設定值
service 加入
getSubscriptionTypes(): Observable<string[]> {return of(['Monthly', 'Annual', '終身']);}
ts 加入
subscriptionTypes: Observable<string[]>;
ngOnInit() { this.subscriptionTypes = this.dataService.getSubscriptionTypes(); }
Html 加入
<option *ngFor="let type of subscriptionTypes | async"> {{ type }} </option>
Form Resources at angular.io
https://angular.tw/resources
有很多整理好的UI 套件
Angular Material
英文小教室
pristine -> adj 原始的;清新的;純樸的
如果內容有誤請多鞭策謝謝