MST

星途 面试题库

面试题:Angular中响应式表单与模板驱动表单在数据验证方面的主要区别

请阐述在Angular中,响应式表单和模板驱动表单在实现数据验证时,从验证方式、验证时机、验证器的定义与使用等方面有哪些主要区别。
48.2万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

验证方式

  • 响应式表单:通过在组件类中使用Validators函数来定义验证规则,以编程方式创建表单控件和验证逻辑。例如:
import { FormControl, Validators } from '@angular/forms';

const username = new FormControl('', [Validators.required, Validators.minLength(3)]);
  • 模板驱动表单:在模板中使用HTML5验证属性(如requiredminlength)或自定义指令来进行验证。例如:
<input type="text" name="username" [(ngModel)]="user.username" required minlength="3">

验证时机

  • 响应式表单:验证会在表单控件的值发生变化时立即触发,实时进行验证。
  • 模板驱动表单:默认情况下,验证在表单提交时触发。但可以通过设置ngModelOptionsupdateOn属性来改变验证时机,如设置为blur,则在失去焦点时验证。例如:
<input type="text" name="username" [(ngModel)]="user.username" required minlength="3" [ngModelOptions]="{updateOn: 'blur'}">

验证器的定义与使用

  • 响应式表单:验证器定义在组件类中,可复用性高。可以通过FormGroupFormArray等对多个控件进行整体验证。例如:
const passwordGroup = new FormGroup({
  password: new FormControl('', Validators.required),
  confirmPassword: new FormControl('', Validators.required)
}, { validators: passwordMatchValidator });

function passwordMatchValidator(group: FormGroup) {
  const password = group.get('password');
  const confirmPassword = group.get('confirmPassword');
  return password.value === confirmPassword.value? null : { passwordMismatch: true };
}
  • 模板驱动表单:验证器定义在模板中,对于复杂的自定义验证逻辑,需要创建自定义指令并在模板中使用。例如,创建一个自定义验证指令passwordMatch
import { Directive, Input, NgModel } from '@angular/core';

@Directive({
  selector: '[passwordMatch]'
})
export class PasswordMatchDirective {
  @Input('passwordMatch') confirmPassword: NgModel;

  constructor(private ngModel: NgModel) {}

  ngOnInit() {
    this.ngModel.valueChanges.subscribe(() => {
      this.validate();
    });
    this.confirmPassword.valueChanges.subscribe(() => {
      this.validate();
    });
  }

  validate() {
    const valid = this.ngModel.value === this.confirmPassword.value;
    this.confirmPassword.control.setErrors(valid? null : { passwordMismatch: true });
  }
}

在模板中使用:

<input type="password" name="password" [(ngModel)]="user.password" required>
<input type="password" name="confirmPassword" [(ngModel)]="user.confirmPassword" passwordMatch="user.password" required>