【问题标题】:Access service from Custom Validator in Angular从 Angular 中的自定义验证器访问服务
【发布时间】:2019-03-12 00:26:36
【问题描述】:

我正在尝试访问我的服务以检查验证器,但我得到的只是充满错误的控制台我确定我只是对语法内容不满意 =/

验证者:

import { DataService } from './services/data.service';
import { AbstractControl, FormGroup } from '@angular/forms';



export function titleValidator(control: AbstractControl,dataService:DataService) {

    console.log(dataService.moviesArray) -->> How can I access this service?
    if (control && (control.value !== null || control.value !== undefined)) {


        if (control.value=="test") {
            return {
                isError: true
            };
        }
    }

    return null;
}

组件:

this.movieForm = this.fb.group({
      title: ['', [Validators.required,titleValidator]],
      ...
    });
  }

如果有人有另一种解决方案来在组件本身中进行自定义验证,我希望得到任何帮助.. 谢谢!

更新:错误:

AddMovieComponent_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'moviesArray' of undefined
    at titleValidator (validator.ts:8)
    at forms.js:602
    at Array.map (<anonymous>)
    at _executeValidators (forms.js:602)
    at FormControl.validator (forms.js:567)
    at FormControl.push../node_modules/@angular/forms/fesm5/forms.js.AbstractControl._runValidator (forms.js:2510)
    at FormControl.push../node_modules/@angular/forms/fesm5/forms.js.AbstractControl.updateValueAndValidity (forms.js:2486)
    at new FormControl (forms.js:2794)
    at FormBuilder.push../node_modules/@angular/forms/fesm5/forms.js.FormBuilder.control (forms.js:5435)
    at FormBuilder.push../node_modules/@angular/forms/fesm5/forms.js.FormBuilder._createControl (forms.js:5473)

【问题讨论】:

  • 请显示错误。并确保您已在您正在使用的组件或 module.ts 中提供服务
  • @AliShahbaz 添加了
  • 很明显moviesArrayundefined,因为您还没有在服务中定义moviesArray 或初始化。
  • 只有在我尝试在此验证器中使用它时才未定义。所有其他地方都初始化了。就像我试图进入那里,我就是不能。例如,即使我在尝试访问它时在数据服务中初始化了一个字符串对象,它也会显示未定义

标签: javascript angular typescript validation


【解决方案1】:

您必须将服务传递给验证器,这里没有依赖注入,因为这不是 Angular 指令,它是一个纯函数。这样做的方法是使用接受服务并创建验证器函数的工厂方法。

export function titleValidator(dataService:DataService): ValidatorFn {
  return (control: AbstractControl) => {
    console.log(dataService.moviesArray) // now you can :)

    // Test for control.value only, for eg:
    if (control.value && dataService.moviesArray.includes(control.value))
      return null;
    else
      return { 'movieNotFound' : { value: control.value } };
  }
}

用法:

this.movieForm = this.fb.group({
  title: ['', [
         Validators.required,
         titleValidator(this.dataService)
  ]],
  ...
});

不需要检查控件是否存在,因为 Angular 只调用具有有效控件的验证器函数。仅测试值。更多信息here

【讨论】:

  • 效果很好,谢谢。另一件事是为什么我看到 console.log 3 次而不是 1 次?
  • Angular 必须在用户输入的不同阶段运行验证函数 3 次。我不能确切地说。如果它对您有用,请为答案投票 :) 我需要 50 声望才能发表评论。
  • 这应该是 2019 年 Angular 7/8 的公认答案。我花了很多时间在相关问题上无用的答案。
猜你喜欢
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 2018-03-08
  • 2022-06-10
  • 2021-09-26
  • 1970-01-01
  • 2018-05-09
相关资源
最近更新 更多