angular - 实现 ControlValueAccessor 和 Validator 的 MatFormFieldControl 创建循环依赖

标签 angular typescript angular-material angular5 angular-components

我正在尝试通过实现 MatFormFieldControl、ControlValueAccessor 和 Validator 接口(interface)来创建自定义表单控件。

但是,当我提供 NG_VALUE_ACCESSORNG_VALIDATORS..

@Component({
  selector: 'fe-phone-number-input',
  templateUrl: './phone-number-input.component.html',
  styleUrls: ['./phone-number-input.component.scss'],
  providers: [
    {
      provide: MatFormFieldControl,
      useExisting: forwardRef(() => PhoneNumberInputComponent)
    },
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => PhoneNumberInputComponent),
      multi: true,
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => PhoneNumberInputComponent),
      multi: true
    }
  ]
})
export class PhoneNumberInputComponent implements MatFormFieldControl<string>,
  ControlValueAccessor, Validator, OnDestroy {
  ...
}

创建了循环依赖:

Uncaught Error: Template parse errors: Cannot instantiate cyclic dependency! NgControl

这个有效:

@Component({
  selector: 'fe-phone-number-input',
  templateUrl: './phone-number-input.component.html',
  styleUrls: ['./phone-number-input.component.scss'],
  providers: [
    {
      provide: MatFormFieldControl,
      useExisting: forwardRef(() => PhoneNumberInputComponent)
    }
  ]
})
export class PhoneNumberInputComponent implements MatFormFieldControl<string>,
  ControlValueAccessor, Validator, OnDestroy {
  ...
  constructor(@Optional() @Self() public ngControl: NgControl) {
    if (this.ngControl) {
      this.ngControl.valueAccessor = this;
    }
  }
}

但我仍然不知道如何进行验证。提供 NG_VALIDATORS 会创建循环依赖。如果不提供它,validate 方法就不会被调用。

我正在使用@angular/material 5.0.4。

最佳答案

为了摆脱循环依赖,我从组件中删除了 Validator 接口(interface),而是直接提供了验证器函数。

export function phoneNumberValidator(control: AbstractControl) {
  ...
}

@Component({
  selector: 'fe-phone-number-input',
  templateUrl: './phone-number-input.component.html',
  styleUrls: ['./phone-number-input.component.scss'],
  providers: [
    {
      provide: MatFormFieldControl,
      useExisting: forwardRef(() => PhoneNumberInputComponent)
    },
    {
      provide: NG_VALIDATORS,
      useValue: phoneNumberValidator,
      multi: true
    }
  ]
})
export class PhoneNumberInputComponent implements MatFormFieldControl<string>,
  ControlValueAccessor, OnDestroy {
  ...
  constructor(@Optional() @Self() public ngControl: NgControl) {
    if (this.ngControl) {
      this.ngControl.valueAccessor = this;
    }
  }
}

关于angular - 实现 ControlValueAccessor 和 Validator 的 MatFormFieldControl 创建循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48682339/

相关文章:

javascript - 将变量清除为 this.x = x 时,Typescript 会抛出错误

angular - 没有将 "exportAs"设置为 "routerLinkActive"的指令

css - Angular Material 6 网格列表对齐元素和对齐内容到 flex-start

javascript - 类型页是 2 个模块错误声明的一部分

angular - 将节点模块导入 Angular typescript /Angular cli的正确方法是什么

javascript - 按枚举名称而不是值对数组进行排序

typescript - Vue3 与强类型 Axios 请求

css - Angular Material - 删除空格

javascript - 如何在 Angular 中选择对象列表的不同属性值

html - Angular 并排显示 2 张卡片