Skip to content

Commit

Permalink
perf(core): avoid rebuild all fields on FieldArray update (#3301)
Browse files Browse the repository at this point in the history
  • Loading branch information
aitboudad committed May 19, 2022
1 parent 89d5fee commit 2f17e73
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 6 deletions.
7 changes: 4 additions & 3 deletions src/core/json-schema/src/formly-json-schema.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,13 +602,14 @@ export class FormlyJsonschema {

private isFieldValid(field: FormlyFieldConfig, schema: JSONSchema7, options: IOptions): boolean {
const model = field.model ? clone(field.model) : (field.fieldArray ? [] : {});
const { form } = (field.options as any)._buildField({
form: Array.isArray(model) ? new FormArray([]) : new FormGroup({}),
const { formControl } = (field.options as any)._buildField({
formControl: Array.isArray(model) ? new FormArray([]) : new FormGroup({}),
fieldGroup: [this._toFieldConfig(schema, { ...options, resetOnHide: true, ignoreDefault: true, map: null, strict: true })],
model,
options: {},
});

return form.valid;
return formControl.valid;
}

private mergeFields(f1: FormlyFieldConfig, f2: FormlyFieldConfig) {
Expand Down
10 changes: 10 additions & 0 deletions src/core/src/lib/components/formly.form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,16 @@ export class FormlyForm implements DoCheck, OnChanges, OnDestroy {
}
};
}

if (!(<any> this.options)._trackModelChanges) {
(this.options as any)._trackModelChanges = (emitModelChange = false) => {
this.clearModelSubscriptions();
this.trackModelChanges(this.fields);
if (emitModelChange) {
this.modelChange.emit(this._modelChangeValue = clone(this.model));
}
};
}
}

private checkExpressionChange() {
Expand Down
5 changes: 4 additions & 1 deletion src/core/src/lib/services/formly.form.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ export class FormlyFormBuilder {

if (!options._buildField) {
options._buildField = (field: FormlyFieldConfig) => {
this.buildForm(field.form, field.fieldGroup, field.model, field.options);
this._setOptions(field.options);
this._buildForm(field);
(field.options as FormlyFormOptionsCache)._checkField(field, true);

return field;
};
}
Expand Down
9 changes: 7 additions & 2 deletions src/core/src/lib/templates/field-array.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export abstract class FieldArrayType<F extends FormlyFieldConfig = FormlyFieldCo

this.model.splice(i, 0, initialModel ? clone(initialModel) : undefined);

(<any> this.options)._buildForm(true);
this._build();
markAsDirty && this.formControl.markAsDirty();
}

Expand All @@ -75,7 +75,12 @@ export abstract class FieldArrayType<F extends FormlyFieldConfig = FormlyFieldCo
this.field.fieldGroup.splice(i, 1);
this.field.fieldGroup.forEach((f, key) => f.key = `${key}`);

(<any> this.options)._buildForm(true);
this._build();
markAsDirty && this.formControl.markAsDirty();
}

private _build() {
(<any> this.options)._buildField(this.field);
(<any> this.options)._trackModelChanges(true);
}
}

0 comments on commit 2f17e73

Please sign in to comment.