表单验证

响应式表单验证
我们在 nz-form-control 上 提供了 nzValidateStatus``nzHasFeedback 等属性,当使用响应式表单时,可以自己定义校验的时机和内容。

  1. nzValidateStatus: 校验状态,默认自动从 nz-form-control 中的 NgControl 获得校验状态,也可以手动指定为特定的 NgControl
  2. nzHasFeedback:用于给输入框添加反馈图标。
  3. nzSuccessTip``nzWarningTip``nzErrorTip``nzValidatingTip:设置不同状态校验文案。

    当同一种状态下存在多种提示情况时,nzSuccessTip``nzWarningTip``nzErrorTip``nzValidatingTip 均支持传入 TemplateRef<{ $implicit: FormControl } 类型,可以通过模板变量)导出 FormControl 后用于切换不同的提示信息。

  1. <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm(validateForm.value)">
  2. <nz-form-item>
  3. <nz-form-label [nzSpan]="7" nzRequired>Username</nz-form-label>
  4. <nz-form-control [nzSpan]="12" nzHasFeedback nzValidatingTip="Validating..." [nzErrorTip]="userErrorTpl">
  5. <input nz-input formControlName="userName" placeholder="async validate try to write JasonWood" />
  6. <ng-template #userErrorTpl let-control>
  7. <ng-container *ngIf="control.hasError('required')">
  8. Please input your username!
  9. </ng-container>
  10. <ng-container *ngIf="control.hasError('duplicated')">
  11. The username is redundant!
  12. </ng-container>
  13. </ng-template>
  14. </nz-form-control>
  15. </nz-form-item>
  16. <nz-form-item>
  17. <nz-form-label [nzSpan]="7" nzRequired>E-mail</nz-form-label>
  18. <nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="emailErrorTpl">
  19. <input nz-input formControlName="email" placeholder="email" type="email" />
  20. <ng-template #emailErrorTpl let-control>
  21. <ng-container *ngIf="control.hasError('email')">
  22. The input is not valid E-mail!
  23. </ng-container>
  24. <ng-container *ngIf="control.hasError('required')">
  25. Please input your E-mail!
  26. </ng-container>
  27. </ng-template>
  28. </nz-form-control>
  29. </nz-form-item>
  30. <nz-form-item>
  31. <nz-form-label [nzSpan]="7" nzRequired>Password</nz-form-label>
  32. <div>
  33. <nz-form-control [nzSpan]="12" nzHasFeedback nzErrorTip="Please input your password!">
  34. <input nz-input type="password" formControlName="password" (ngModelChange)="validateConfirmPassword()" />
  35. </nz-form-control>
  36. </div>
  37. </nz-form-item>
  38. <nz-form-item>
  39. <nz-form-label [nzSpan]="7" nzRequired>Confirm Password</nz-form-label>
  40. <nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="passwordErrorTpl">
  41. <input nz-input type="password" formControlName="confirm" placeholder="confirm your password" />
  42. <ng-template #passwordErrorTpl let-control>
  43. <ng-container *ngIf="control.hasError('required')">
  44. Please confirm your password!
  45. </ng-container>
  46. <ng-container *ngIf="control.hasError('confirm')">
  47. Password is inconsistent!
  48. </ng-container>
  49. </ng-template>
  50. </nz-form-control>
  51. </nz-form-item>
  52. <nz-form-item>
  53. <nz-form-label [nzSpan]="7" nzRequired>Comment</nz-form-label>
  54. <nz-form-control [nzSpan]="12" nzErrorTip="Please write something here!">
  55. <textarea formControlName="comment" nz-input rows="2" placeholder="write any thing"></textarea>
  56. </nz-form-control>
  57. </nz-form-item>
  58. <nz-form-item>
  59. <nz-form-control [nzOffset]="7" [nzSpan]="12">
  60. <button nz-button nzType="primary" [disabled]="!validateForm.valid">Submit</button>
  61. <button nz-button (click)="resetForm($event)">Reset</button>
  62. </nz-form-control>
  63. </nz-form-item>
  64. </form>
  1. import { Component } from '@angular/core';
  2. import { FormBuilder, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms';
  3. import { Observable, Observer } from 'rxjs';
  4. @Component({
  5. selector: 'nz-demo-form-validate-reactive',
  6. templateUrl: `./form.html`,
  7. styles: [
  8. `
  9. [nz-form] {
  10. max-width: 600px;
  11. }
  12. button {
  13. margin-left: 8px;
  14. }
  15. `
  16. ]
  17. })
  18. export class NzDemoFormValidateReactiveComponent {
  19. validateForm: FormGroup;
  20. submitForm(value: any): void {
  21. for (const key in this.validateForm.controls) {
  22. this.validateForm.controls[key].markAsDirty();
  23. this.validateForm.controls[key].updateValueAndValidity();
  24. }
  25. console.log(value);
  26. }
  27. resetForm(e: MouseEvent): void {
  28. e.preventDefault();
  29. this.validateForm.reset();
  30. for (const key in this.validateForm.controls) {
  31. this.validateForm.controls[key].markAsPristine();
  32. this.validateForm.controls[key].updateValueAndValidity();
  33. }
  34. }
  35. validateConfirmPassword(): void {
  36. setTimeout(() => this.validateForm.controls.confirm.updateValueAndValidity());
  37. }
  38. userNameAsyncValidator = (control: FormControl) =>
  39. new Observable((observer: Observer<ValidationErrors | null>) => {
  40. setTimeout(() => {
  41. if (control.value === 'JasonWood') {
  42. // you have to return `{error: true}` to mark it as an error event
  43. observer.next({ error: true, duplicated: true });
  44. } else {
  45. observer.next(null);
  46. }
  47. observer.complete();
  48. }, 1000);
  49. });
  50. confirmValidator = (control: FormControl): { [s: string]: boolean } => {
  51. if (!control.value) {
  52. return { error: true, required: true };
  53. } else if (control.value !== this.validateForm.controls.password.value) {
  54. return { confirm: true, error: true };
  55. }
  56. return {};
  57. };
  58. constructor(private fb: FormBuilder) {
  59. this.validateForm = this.fb.group({
  60. userName: ['', [Validators.required], [this.userNameAsyncValidator]],
  61. email: ['', [Validators.email, Validators.required]],
  62. password: ['', [Validators.required]],
  63. confirm: ['', [this.confirmValidator]],
  64. comment: ['', [Validators.required]]
  65. });
  66. }
  67. }

radio, checkbox响应式表单

目前没研究出用法,文档只有单个checkbox true/false
可能用模板驱动方式可以
参考:字段重构组件库的checkbox —— web/framework
formArray
这个例子不是很正确
Angular原生,官方文档关于radio,select的用法
Issue