自定义 ValidatorFn 使用附加参数

Custom ValidatorFn use aditional parameters

目前我已经尝试了下面的代码,但我还没有使用额外的数据。

创建-room.component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DialogData } from '../game.component';

@Component({
  selector: 'app-create-room',
  templateUrl: './create-room.component.html',
  styleUrls: ['./create-room.component.scss']
})
export class CreateRoomComponent implements OnInit {
  form!: FormGroup;
  
  constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData, private _formBuilder: FormBuilder, private dialogRef: MatDialogRef<CreateRoomComponent>) { }

  ngOnInit(): void {
    this.form = this._formBuilder.group({
      roomInput: new FormControl("", [Validators.required]),
    }, {validator: roomValidator}); 
  }
  
  ...
}

export const roomValidator: ValidatorFn = (formGroup: AbstractControl ): ValidationErrors | null  => {
  /* Check if the room name already exists */
  var roomName: string = formGroup.get('roomInput')?.value;

  // use data from MAT_DIALOG_DATA INJECT here

  if (true) {
    return { nameWrong: true };
  }

  return null;
}

如何使用对话框在自定义 ValidatorFn 中接收到的数据。

我应该将 this.data 作为参数传递吗?

您有多种选择:

  • data 作为参数传递给验证器
  • 添加 NG_VALUE_ACCESSOR 并实施 ControlValueAccessor 以创建自定义表单组验证

将您的验证器定义更改为一个函数,该函数可以接受您需要的任何参数,并且 returns a ValidatorFn:

export const roomValidator = (data: DialogData): ValidatorFn => {
  return (formGroup: AbstractControl ): ValidationErrors | null  => {
    /* Check if the room name already exists */
    var roomName: string = formGroup.get('roomInput')?.value;

    // use data param

    if (true) {
      return { nameWrong: true };
    }

    return null;
  }
}

然后像这样使用它:

  ngOnInit(): void {
    this.form = this._formBuilder.group({
      roomInput: new FormControl("", [Validators.required]),
    }, {validator: roomValidator(this.data)}); 
  }