我编写了这个定制验证器:

import { AbstractControl, ValidationErrors, ValidatorFn } from "@angular/forms";

export function notInSet(theSet: Set<string>): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        const val = control.value;
        if(theSet.has(val))
            return {InSet: true};
        else
            return null;
    }
}

现在在我的模板中,我有以下内容:

    <form #myForm novalidate>
        <input pInputText [(ngModel)]="name" name="name" notInSet="existingNames" #theName="ngModel"/>
        <div *ngIf="!theName.valid" class="text-error">
            Please provide a unique name for this api
        </div>
    </form>

这里,existingNamesname被定义为对应的ts文件.

问题是从未调用过该验证器.我觉得我必须在某个地方登记,但我真的不确定在哪里.

推荐答案

你需要创建一个指令当你使用模板驱动的表单自定义验证器,这里是一个关于Stackblitz的工作例子,你可以通过它来实现你的功能,如果有任何疑问,请让我知道!

指令

import { Directive, Input } from '@angular/core';
import {
  NG_VALIDATORS,
  Validator,
  AbstractControl,
  ValidationErrors,
} from '@angular/forms';

@Directive({
  selector: '[notInSet]',
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: NotInSetDirective,
      multi: true,
    },
  ],
  standalone: true,
})
export class NotInSetDirective implements Validator {
  @Input() notInSet!: Map<string, number>;
  constructor() {}

  validate(control: AbstractControl): { [key: string]: any } | null {
    const val = control.value;
    if (this.notInSet.has(val)) return { InSet: true };
    else return null;
  }
}

双手

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import 'zone.js';
import { CommonModule } from '@angular/common';
import { NotInSetDirective } from './validator.指令';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule, FormsModule, NotInSetDirective],
  template: `
    <form #myForm novalidate>
        <input pInputText [(ngModel)]="name" name="name" [notInSet]="existingNames" #theName="ngModel"/>
        <div *ngIf="!theName.valid" class="text-error">
            Please provide a unique name for this api
        </div>
        {{theName.valid | json}}
    </form>
  `,
})
export class App {
  name = 'Angular';
  existingNames = new Map([
    ['apples', 1],
    ['bananas', 1],
    ['oranges', 1],
  ]);
}

bootstrapApplication(App);

stackbitz

Typescript相关问答推荐

如何在ts中使用函数重载推断参数类型

如何为ViewContainerRef加载的Angular组件实现CanDeactivate保护?

泛型函数类型验证

SortKey类型不起作用,尽管它使用的单个类型工作正常<>'

类型脚本强制泛型类型安全

如何正确地对类型脚本泛型进行限制

在动态对话框中使用STEP组件实现布线

对于合并对象中的可选属性(例如选项),类型推断可能是错误的

带switch 的函数的返回类型的类型缩小

是否可以从函数类型中创建简化的类型,go 掉参数中任何看起来像回调的内容,而保留其余的内容?

如果数组使用Reaction-Hook-Form更改,则重新呈现表单

Angular 自定义验证控件未获得表单值

类型推断对React.ForwardRef()的引用参数无效

TypeScrip:从嵌套的对象值创建新类型

有没有什么方法可以使用ProvideState()提供多个削减器作为根减减器

映射类型不是数组类型

TypeScript中的这些条件类型映射方法之间有什么区别?

如何知道使用TypeScript时是否在临时工作流内运行

React-Router V6 中的递归好友路由

根据索引将元组拆分为两个块