Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 如何从字符串中获取验证程序函数_Angular_Typescript_Angular5 - Fatal编程技术网

Angular 如何从字符串中获取验证程序函数

Angular 如何从字符串中获取验证程序函数,angular,typescript,angular5,Angular,Typescript,Angular5,如何将以下字符串数组转换为类型数组(或函数,或这些验证器是什么…? let valStrings: string[] = ["Validators.required", "Validators.maxLength(10)"]; 并将其转换为: let validators: ValidatorFn[] = [ Validators.required, Validators.maxLength(10) ]; 我有一个web服务返回验证规则。这是一种集中所有验证规则以保持服务器和客户端验证同步的

如何将以下字符串数组转换为类型数组(或函数,或这些验证器是什么…

let valStrings: string[] = ["Validators.required", "Validators.maxLength(10)"];
并将其转换为:

let validators: ValidatorFn[] = [ Validators.required, Validators.maxLength(10) ];
我有一个web服务返回验证规则。这是一种集中所有验证规则以保持服务器和客户端验证同步的尝试,因此字符串来自带有JSON结果的
HttpClient
调用。 当然,我们仍然将实际实现分开,但至少定义的规则应该在两者之间相同

这个验证器数组将被传递到
FormControl
中,以使用Angular中的反应式表单进行客户端验证

这是不是应该使用
eval()
的地方


谢谢-Adam用字符串中的angular代码在服务器上定义验证是一个非常糟糕的主意。如果需要动态验证,请为此创建API。比如:

validations: {
  name: {
    maxLength: 10,
    required: true
  }
}
Eval不会帮助您,因为代码中没有绑定该类。此外,eval还带来安全风险,CSP应在您的站点上禁用它

不要将字符串转换为代码。您需要一个解析器来实现这一点。当他们在Angular中更改验证时,您会怎么做?你会更新你所有的表格吗


或者想象一下,您将使用iOS应用程序连接到您的API。它必须解析这些字符串角度验证规则。

我知道的唯一方法是使用if

let valStrings: string[] = ["Validators.required", "Validators.maxLength(10)"];
let validators=valString.map(x=>{
    switch (x)
    {
        if (x=="Validators.required")
            return Validators.required;
        if (x.startsWith("Validators.maxLength")
        {
            let length=+(x.split('(')[1].split(')')[0]);
            return Validators.maxLength(length)
        }
    }
});

您可以在抽象服务中创建验证映射,并在需要时重用


export const schema = {
    "defaultValidations": {
        'title': [
            { name: 'required' },
            { name: 'minLength', args: [3] }
        ],
        'firstName': [
            { name: 'required' },
            { name: 'minLength', args: [3] },
            { name: 'maxLength', args: [50] }
        ]
    }
}

export interface Dictionary<T> {
    [Key: string]: T;
}

  validationMap: Dictionary<any> = {
    "required": (arg: any[]) => Validators.required,
    "minLength": (arg: number[]) => Validators.minLength(arg[0]),
    "maxLength": (arg: number[]) => Validators.maxLength(arg[0])
  };

  constructor(private fb: FormBuilder) { }

  // validation functions
  mapValiations(key: string) :ValidatorFn[] {
    const validations = schema.defaultValidations[key]?.map(element => {
        return this.validationMap[element.name](element?.args);
     });

     return validations;
  }


导出常量架构={
“defaultValidations”:{
“标题”:[
{name:'必需'},
{name:'minLength',args:[3]}
],
“名字”:[
{name:'必需'},
{name:'minLength',args:[3]},
{name:'maxLength',args:[50]}
]
}
}
导出接口字典{
[键:字符串]:T;
}
validationMap:字典={
“必需”:(arg:any[])=>Validators.required,
“minLength”:(arg:number[])=>Validators.minLength(arg[0]),
“maxLength:(arg:number[])=>验证器。maxLength(arg[0])
};
构造函数(私有fb:FormBuilder){}
//验证函数
mapValiations(键:字符串):验证器fn[]{
const validations=schema.defaultValidations[key]?.map(元素=>{
返回此.validationMap[element.name](element?.args);
});
返回验证;
}

我会更新数据库中的“ClientValidationFunction”列:)。我当然希望他们不要在验证方面做出重大改变。我的意思是,如果我在代码中使用验证,并且他们对其进行了更新,它仍然会被破坏。不过,我不会在API上关注你。您的意思是简单地从我的Web服务解析json主体(这就是您答案中的代码片段所代表的)并以这种方式应用验证吗?我同意eval的观点,这就是为什么我没有深入研究的原因。感谢您使用定义JSON API来定义验证。。。然后检查来自API的内容,并将其应用到Angular中。想象一下,你将IOS应用程序连接到你的应用程序。。。它必须解析角度代码。是的,这是一个很好的观点。理想情况下,json将是与客户端平台无关的,并且该依赖关系不是bueno。。。我想从长远来看我喜欢这种方法(这将写在我的墓碑上)。现在,我采取了与Eliseo提到的类似的方法,但我希望在这次冲刺之后有机会重构它。是的,这意味着你真的需要Eliseo制作的解析器。。。即使是短期内,我也会避免这种解决方案。@pratikch在构建表单时,根据对象键添加验证器。谢谢您的回答。这与我最后所做的非常相似(我将args正则化为off并使用switch语句,但除此之外,它是相同的),但我希望在有更多时间时返回,并更像Martin建议的那样进行处理