## Template-driven forms - 5 --- ![](https://i.imgur.com/zAB6dKg.png) --- ## NgModel https://angular.io/api/forms/NgModel ![](https://i.imgur.com/WkOAGJ1.png) --- ## NgModel * 建立FormControl實體 * 追蹤表單輸入或選取值 * 追蹤表單修改狀態與驗證 * 維持表單元件與Model同步 --- #### 直接使用Model進行資料綁定 單向綁定 ```typescript= <input name="account" [ngModel]="account" #account="ngModel"/> ``` 雙向綁定 ```typescript= <input name="account" [(ngModel)]="account" #account="ngModel"/> ``` 錯誤範例 ```typescript= <input name="account" value="test" [ngModel]="account"/> ``` --- ### NgModel exportAs ```typescript= <input name="account" required [(ngModel)]="account" #account="ngModel"/> <div *ngIf="account?.errors?.required"> 該欄位不能為空 </div> ``` ![](https://i.imgur.com/i1R89ol.png) https://angular.io/guide/forms --- ### 內建Validators https://angular.io/api/forms/Validators --- ### 表單驗證CSS樣式 ![](https://i.imgur.com/m2o3GFE.png) --- ### NgModel Name * 獨立存在 ```typescript= <input required [(ngModel)]="account" #account="ngModel"/> ``` * 於 `<form>` tag內 ```typescript= <form> <input name="account" required [(ngModel)]="account" #account="ngModel"/> </form> ``` --- ## ngModelOptions ```typescript= @Input('ngModelOptions') options: { name?: string; standalone?: boolean; updateOn?: FormHooks; } ``` https://angular.io/api/forms/NgModel#using-ngmodel-on-a-standalone-control --- ### ngModelOptions standalone ```typescript= <form> <my-person-control ngModel [ngModelOptions]="{standalone: true}"> </my-person-control> </form> ``` --- ### ngModelOptions name ```typescript= <form> <my-person-control name="Nancy" ngModel [ngModelOptions]="{name: 'user'}"> </my-person-control> </form> <!-- form value: {user: ''} --> ``` --- ### NgModel 屬性 https://angular.io/api/forms/NgModel --- # NgForm --- ## NgForm * 追蹤群組內Form Control 狀態 * 預設綁定`<form>` * ExportAs ngForm --- ### NgForm 屬性 https://angular.io/api/forms/NgForm --- ### ngSubmit ```typescript= <form (ngSubmit)="onSubmit(f)" #f="ngForm"> <input name="username" ngModel/> <button type="submit">Submit</button> </form> ``` ```typescript= <form #f="ngForm"> <input name="username" ngModel/> <button type="button" (click)="onSubmit(f)">Submit</button> </form> ``` --- <!-- ## NgForm - value ### 取得欄位值的注意事項 * 預設 --- --> # NgModelGroup --- ## NgModelGroup * 建立欄位群組 * 只能使用在有`<form>`標籤內 * 建立表單群組`FormGroup` * 追蹤取得群組內表單控制項的狀態 --- ## NgModelGroup屬性 https://angular.io/api/forms/NgModelGroup --- # Validation --- ## Custom Validators --- ```typescript= @Directive({ selector: '[appAge]', providers: [{provide: NG_VALIDATORS, useExisting: AgeValidatorDirective, multi: true}] }) export class AgeValidatorDirective implements Validator { @Input('appAge') appAge: number; validate(control: AbstractControl): {[key: string]: any} | null { return control.value >= this.appAge ? null : {'ageLimit': true}; } } ``` ```htmlmixed= <input name="age" appAge="18" ngModel/> ``` --- ## Cross Field Validation --- ```typescript= @Directive({ selector: '[appCompare]', providers: [{ provide: NG_VALIDATORS, useExisting: CompareDirective, multi: true }] }) export class CompareDirective implements Validator { @Input('appCompare') compareControlKey: string; constructor() { } validate(control: AbstractControl): { [key: string]: any; } { const compareControl = control.root.get(this.compareControlKey); const valid = this.compareControlKey && compareControl.value && control.value === compareControl.value; return valid ? null : { 'compare': { value: c.value } }; } } ``` ```htmlmixed= <form> <input name="password" ngModel required/> <input name="password2" ngModel required appCompare="password"/> </form> ``` --- ## Custom Async Validator --- ```typescript= @Directive({ selector: '[appAgeValidator]', providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: AgeValidatorDirective, multi: true}] }) export class AgeValidatorDirective implements AsyncValidator{ constructor() { } validate(control: AbstractControl): Observable<ValidationErrors|null> { return of({'custom': true}); } } ``` ```htmlmixed= <form> <input name="account" type="text" ngModel appAgeValidator #mAccount="ngModel" required> </form> ``` --- # FormsModule https://angular.io/api/forms/FormsModule --- ## ControlValueAccessor https://github.com/angular/angular/blob/master/packages/forms/src/directives/radio_control_value_accessor.ts --- ## 自訂 NG_VALUE_ACCESSOR https://ithelp.ithome.com.tw/articles/10204510 --- EIP-NG ---
{"metaMigratedAt":"2023-06-15T09:48:16.618Z","metaMigratedFrom":"YAML","title":"Template-driven forms","breaks":true,"description":"2020/06/22 新人課程","contributors":"[{\"id\":\"79a6af84-a897-462e-9bd4-c64e37dcd72b\",\"add\":4709,\"del\":54}]"}
    369 views