Angular动态表单生成(四)
ng-dynamic-forms实践篇(下)
我们接着上篇,先把小目标中的所有字段都定义出来
这部分就是苦力活儿了,把KendoUiComponent中的formModel完善即可:
1 formModel: DynamicFormControlModel[] = [ 2 new DynamicInputModel({ 3 id: 'firstName', 4 label: '姓名', 5 placeholder: '请输入用户姓名' 6 }), 7 new DynamicRadioGroupModel({ 8 id: 'sex', 9 legend: '性别', 10 options: [ 11 { 12 label: '男', 13 value: 'M' 14 }, 15 { 16 label: '女', 17 value: 'F' 18 } 19 ] 20 }), 21 new DynamicInputModel({ 22 id: 'age', 23 inputType: 'number', 24 label: '年龄', 25 placeholder: '请输入用户年龄', 26 min: 0, 27 max: 150, 28 step: 1, 29 value: 18 30 }), 31 new DynamicDatePickerModel({ 32 id: 'birthday-date', 33 inline: false, 34 label: '出生日期', 35 placeholder: '请选择出生日期' 36 }), 37 new DynamicTimePickerModel({ 38 id: 'birthday-time', 39 label: '出生时分', 40 format: 'HH:mm' 41 }), 42 new DynamicInputModel({ 43 id: 'password', 44 inputType: 'password', 45 label: '密码', 46 placeholder: '请输入用户密码' 47 }), 48 new DynamicInputModel({ 49 id: 'password-confirm', 50 inputType: 'password', 51 label: '确认密码', 52 placeholder: '请再次输入用户密码' 53 }), 54 new DynamicSelectModel({ 55 id: 'education', 56 label: '学历', 57 options: [ 58 { 59 label: '大学', 60 value: 'university' 61 }, 62 { 63 label: '高中', 64 value: 'high-school' 65 }, 66 { 67 label: '初中', 68 value: 'junior-school' 69 }, 70 ] 71 }), 72 new DynamicCheckboxGroupModel({ 73 id: 'favorite', 74 legend: '兴趣爱好', 75 group: [ 76 new DynamicCheckboxModel({ 77 id: 'play-games', 78 label: '打游戏' 79 }), 80 new DynamicCheckboxModel({ 81 id: 'coding', 82 label: '写代码' 83 }), 84 new DynamicCheckboxModel({ 85 id: 'running', 86 label: '跑步' 87 }), 88 ] 89 }), 90 new DynamicTextAreaModel({ 91 id: 'remark', 92 label: '备注', 93 rows: 10 94 }), 95 new DynamicFileUploadModel({ 96 autoUpload: true, 97 id: 'attachments', 98 label: 'Attachments', 99 multiple: true, 100 removeUrl: 'removeUrl', 101 url: 'saveUrl' 102 }), 103 new DynamicFileUploadModel( 104 { 105 id: 'head-photo', 106 label: '头像', 107 accept: '*.*', 108 autoUpload: true, 109 multiple: true, 110 removeUrl: 'removeUrl', 111 url: 'http://localhost:60155/api/file/upload' 112 } 113 ) 114 ];
这里的各种控件模型的初始化,可以查看DynamicXXXXModel的属性定义, 也可以参考官方github里面的examples:https://github.com/udos86/ng-dynamic-forms/blob/master/sample/app/ui-kendo/kendo-sample-form.model.ts。
接下来,我们再尝试加一下验证相关的代码:
验证分两类,一类是系统内置的验证,比如非空验证、最大长度、最大值、正则表达式之类的,另外一类是自定义的验证逻辑,下面我们分别来看看怎么用吧~
系统内置验证
这个用起来比较简单,直接在模型上加上validators属性和errorMessages属性即可,如下代码:
new DynamicInputModel({ id: 'firstName', label: '姓名', placeholder: '请输入用户姓名', validators: { required: null, maxLength: 15 }, errorMessages: { required: '{{label}}不能为空', maxLength: '{{label}}不能超过15个字符' } })
其中validators中定义了你需要做哪些验证,以及这些验证方法需要传递的参数是什么。errorMessages中定义了当错误发生时的错误消息。最终效果如下:
自定义验证
有时候,系统验证不完全能满足我们的需求,此时需要自己定义一些验证的方法。比如,我们需要在用户注册时,检查用户两次输入的密码是否一致。
在使用时,首先我们需要定义一个验证的方法,代码如下,该方法中,会将password和password-confirm从表单中取出,并获得value,如果他们两个的Value不一致,则返回对象:{customMatchPasswordValidator: true}
import {AbstractControl, FormGroup, ValidationErrors} from '@angular/forms'; export function customMatchPasswordValidator(group: FormGroup): ValidationErrors | null { console.log(group); console.log(group.get('password')); const password = group.get('password').value, passWordConfirm = group.get('password-confirm').value; const hasError = password != passWordConfirm; return hasError ? {customMatchPasswordValidator: true} : null; }
然后在app.modules.ts中导入它:
import {customMatchPasswordValidator} from './kendo-ui/password-validation';
还需要在app.modules.ts的providers中注入:
providers: [ { provide: NG_VALIDATORS, useValue: customMatchPasswordValidator, multi: true }, { provide: DYNAMIC_VALIDATORS, useValue: new Map<string, Validator | ValidatorFactory>([ ['customMatchPasswordValidator', customMatchPasswordValidator] ]) } ]
由于是要同时获取两个控件的值,所以需要将两个密码框的模型放到一个DynamicFormGroupModel中,并且我们的验证也需要加到DynamicFormGroupModel中,代码如下:
new DynamicFormGroupModel({ id: 'password-group', group: [ new DynamicInputModel({ id: 'password', inputType: 'password', label: '密码', placeholder: '请输入用户密码' }), new DynamicInputModel({ id: 'password-confirm', inputType: 'password', label: '确认密码', placeholder: '请再次输入用户密码' }) ], validators: { customMatchPasswordValidator: null }, errorMessages: { customMatchPasswordValidator: '密码输入不不匹配' } })
这样,我们就可以完成密码的校验了,效果如下:
截止这里,小目标中的其他组件也都类似,这里就不一一例举了