主要参考官方文档和Github

另一插件:ng-dynamic-forms

Tutorial 动态创建表单

Example

Expression Properties

根据model的值是否disable等

  1. expressionProperties: {
  2. 'templateOptions.disabled': '!model.text',
  3. }

Form State

  1. options: FormlyFormOptions = {
  2. formState: {
  3. disabled: true,
  4. },
  5. }
  6. fields: FormlyFieldConfig[] = [
  7. {
  8. key: 'city',
  9. expressionProperties: {
  10. // apply expressionProperty for disabled based on formState
  11. 'templateOptions.disabled': 'formState.disabled',
  12. },
  13. }
  14. ];

Default Value

默认值
1. Default the model (preferred)

  1. model = {
  2. lastName: 'Smith',
  3. };
  1. Use the defaultValue option on the field
    1. defaultValue: 'This is a default value'

    Hide Fields

    隐藏表单域
    1. hideExpression: '!model.name',

    modelOptions

    验证方式
    1. fields: FormlyFieldConfig[] = [
    2. {
    3. key: 'city',
    4. modelOptions: {
    5. debounce: {
    6. default: 2000,
    7. },
    8. modelOptions: {
    9. updateOn: 'blur',
    10. }
    11. modelOptions: {
    12. updateOn: 'submit',
    13. }
    14. }
    15. }];
  1. export function RequiredValidatorMessage(err, field: FormlyFieldConfig) {
  2. return `"This required field was validated after ${field.formControl.updateOn}"`;
  3. }
  4. FormlyModule.forRoot({
  5. validationMessages: [
  6. {
  7. name: 'required',
  8. message: RequiredValidatorMessage,
  9. },
  10. ],
  11. })

Reset Model

作用就是,每当updateInitialValue,之后进行resetModel,model值就恢复为这次updateInitialValue的值。

  1. <button (click)="options.resetModel()">Reset</button>
  2. <button (click)="options.updateInitialValue()">Update Intial Values</button>

Built-in validations

Angular内置验证
required, min, max, minLength, maxLength, pattern等

  1. {
  2. key: 'ip',
  3. type: 'input',
  4. templateOptions: {
  5. label: 'IP Address (pattern = /(\d{1,3}\.){3}\d{1,3}/)',
  6. pattern: /(\d{1,3}\.){3}\d{1,3}/,
  7. required: true,
  8. },
  9. validation: {
  10. messages: {
  11. pattern: (error, field: FormlyFieldConfig) => `"${field.formControl.value}" is not a valid IP Address`,
  12. },
  13. }

validation

四种方式,主要区别在于是在 FormlyModule.forRoot 中定义,还是field中定义。
文档中的’[As the case above]’一般是指与前面一种方式的定义相同,例如message的定义。
一般采用方式三。

Custom validation

官方example

  1. IP Address (using custom validation declared in ngModule)


  1. IP Address (using custom validation through validators.validation property)

  2. IP Address (using custom validation through validators.expression property)###

    Validation message

    官方example

  3. Name (custom validation message declared in ngModule)


  1. IP Address (custom validation message through validation property)


  1. IP Address (custom validation message through validators property)

    Async validation and updateOn

    ``typescript fields: FormlyFieldConfig[] = [ { key: 'text', type: 'input', templateOptions: { label: 'Username (validated onblur`)’, placeholder: ‘Username’, required: true, }, modelOptions: { updateOn: ‘blur’, }, asyncValidators: { uniqueUsername: {
    1. expression: (control: FormControl) => {
    2. return new Promise((resolve, reject) => {
    3. setTimeout(() => {
    4. resolve(this.existingUsers.indexOf(control.value) === -1);
    5. }, 1000);
    6. });
    7. },
    8. message: 'This username is already taken.',
    }, }, }, ];
  1. <a name="PMDue"></a>
  2. ## Matching Two Fields
  3. 确认密码<br />主要是 `fieldMatch` 和 `fieldGroup` 两个属性
  4. <a name="fk7N0"></a>
  5. ## Force showing error state
  6. 初始就显示格式不对
  7. ```typescript
  8. validation: {
  9. show: true,
  10. }

Toggle required field

Disable submit button

  1. <button [disabled]="!form.valid">Submit</button>

Bind Observables to Select

可以直接用可观察对象赋值给templateOptions,但是不能同步设置model
因此可能还是需要异步处理。

Formly Expressions

You can use hideExpression to hide fields dynamically and Expression Properties for allows you to dynamically change many properties of a field.

  1. export class AppComponent {
  2. options = {
  3. formState: {
  4. // formState.mainModel指向这个表单的model
  5. mainModel: this.model,
  6. }
  7. }
  8. }
  9. fields: FormlyFieldConfig[] = [
  10. {
  11. key: 'country',
  12. type: 'input',
  13. templateOptions: {
  14. label: 'field 2',
  15. placeholder: ''
  16. },
  17. expressionProperties: {
  18. 'templateOptions.disabled': (model: any, formState: any, field: FormlyFieldConfig) => {
  19. // access to the main model can be through `this.model` or `formState` or `model
  20. return !formState.mainModel.text
  21. },
  22. }
  23. }
  24. ]
  1. fields: FormlyFieldConfig[] = [
  2. {
  3. key: 'country',
  4. type: 'input',
  5. templateOptions: {
  6. label: 'City',
  7. placeholder: 'set to 123'
  8. },
  9. hideExpression: (model: any, formState: any, field: FormlyFieldConfig) => {
  10. // access to the main model can be through `this.model` or `formState` or `model
  11. if (formState.mainModel && formState.mainModel.city) {
  12. return formState.mainModel.city !== "123"
  13. }
  14. return true;
  15. }
  16. }
  17. ]

关于model和value

  1. model用于初始化formly的时候的默认值
  2. html渲染出表单之前,value与model是相同的;渲染之后,value进行了初始化赋值,与model不同了

可以采用setTimeout获得真正的value值

  1. 对formly克隆,用cloneDeep无法克隆到form(修改克隆的表单,也会触发原表单的modelChange),需要new Group({})才能脱离与原来formly的关系。

    关于modelChange

    modelChange是对Angular的valueChanges进行的过滤。valueChanges会在form的每个field变更时触发,formly版本5.5.8修改了modelChange,只触发一次。但是何时触发会有一些问题,例如表单重构项目中材质成分字段,修改时不能触发modelChange.
  • field的hide从false变为true时,会进行一次控件注册,会进行变更检测。

    Tips

  1. formly.form.value会在nextTick才更新,用formly.model
  2. 不能存到ngxs,ngxs为单向数据流,会把对象变为不可扩展

image.png

  1. 多个config导入问题

Extension not called in production mode. #1624

  1. formly类型和angular类型不一致

    API

    ```typescript /**
    • An object with a few useful properties
      • validation.messages: A map of message names that will be displayed when the field has errors.
      • validation.show: A boolean you as the developer can set to force displaying errors whatever the state of field. This is useful when you’re trying to call the user’s attention to some fields for some reason. */ validation?: { messages?: { [messageProperties: string]: string | ((error: any, field: FormlyFieldConfig) => string); }; show?: boolean;
  1. [additionalProperties: string]: any;

};

/**

  • Used to set validation rules for a particular field.
  • Should be an object of key - value pairs. The value can either be an expression to evaluate or a function to run.
  • Each should return a boolean value, returning true when the field is valid. See Validation for more information. *
  • {
  • validation?: (string | ValidatorFn)[];
  • [key: string]: ((control: AbstractControl, field: FormlyFieldConfig) => boolean) | ({ expression: (control: AbstractControl, field: FormlyFieldConfig) => boolean, message: string | ((error, field: FormlyFieldConfig) => string) });
  • } */ validators?: any; ```