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建议的那样进行处理