如何将以下字符串数组转换为类型的数组(或函数?或这些验证器都...)?
let valStrings: string[] = ["Validators.required", "Validators.maxLength(10)"];
并将其转换为:
let validators: ValidatorFn[] = [ Validators.required, Validators.maxLength(10) ];
我有一个返回验证规则的Web服务。这是尝试集中所有验证规则,以使服务器和客户端验证保持同步,因此字符串来自带有JSON结果的HttpClient
调用。
当然,我们仍然将实际的实现分开,但是至少在两者之间定义的规则应该是相同的。
此验证器数组将被传递到FormControl
中,以利用Angular中的反应形式进行客户端验证。
这是应该使用eval()
的地方吗?
谢谢-亚当
答案 0 :(得分:2)
通过字符串中的angular代码在服务器上定义验证是非常糟糕的主意。如果要进行动态验证,请为此创建一个API。喜欢:
heroku pg:copy DATABASE_URL HEROKU_POSTGRESQL_ROSE_URL --app my_app_name --confirm my_app_name
Eval不会帮助您,因为该类未捆绑在代码中。此外,eval还会带来安全风险,因此应该由CSP在您的站点上禁用它。
不将字符串转换为代码。您将需要一个解析器。当他们在Angular中更改验证时,您会怎么做?您会更新所有表格吗?
或者想象您将通过iOS应用程序连接到您的API。必须解析这些字符串Angular验证规则。
答案 1 :(得分:1)
我知道的唯一方法是使用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)
}
}
});
答案 2 :(得分:0)
您可以在抽象服务中创建验证映射,并在需要时重用。
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;
}