/
array.property.ts
120 lines (105 loc) · 3.75 KB
/
array.property.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { Injector } from '@angular/core';
import { AlainSFConfig } from '@delon/util/config';
import { deepCopy } from '@delon/util/other';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';
import { FormProperty, PropertyGroup } from './form.property';
import { FormPropertyFactory } from './form.property.factory';
import { ObjectProperty } from './object.property';
import { SF_SEQ } from '../const';
import { SFValue } from '../interface';
import { SFSchema } from '../schema/index';
import { SFUISchema, SFUISchemaItem } from '../schema/ui';
import { SchemaValidatorFactory } from '../validator.factory';
export class ArrayProperty extends PropertyGroup {
constructor(
injector: Injector,
private formPropertyFactory: FormPropertyFactory,
schemaValidatorFactory: SchemaValidatorFactory,
schema: SFSchema,
ui: SFUISchema | SFUISchemaItem,
formData: Record<string, unknown>,
parent: PropertyGroup | null,
path: string,
options: AlainSFConfig
) {
super(injector, schemaValidatorFactory, schema, ui, formData, parent, path, options);
this.properties = [];
}
getProperty(path: string): FormProperty | undefined {
const subPathIdx = path.indexOf(SF_SEQ);
const pos = +(subPathIdx !== -1 ? path.substring(0, subPathIdx) : path);
const list = this.properties as PropertyGroup[];
if (isNaN(pos) || pos >= list.length) {
return undefined;
}
const subPath = path.substring(subPathIdx + 1);
return list[pos].getProperty(subPath);
}
setValue(value: SFValue, onlySelf: boolean): void {
this.properties = [];
this.clearErrors();
this.resetProperties(value);
this.cd(onlySelf);
this.updateValueAndValidity({ onlySelf, emitValueEvent: true });
}
resetValue(value: SFValue, onlySelf: boolean): void {
this._value = value || this.schema.default || [];
this.setValue(this._value, onlySelf);
}
_hasValue(): boolean {
return true;
}
_updateValue(): void {
const value: NzSafeAny[] = [];
this.forEachChild((property: FormProperty) => {
if (property.visible) {
value.push({ ...(this.widget?.cleanValue ? null : property.formData), ...property.value });
}
});
this._value = value;
}
private addProperty(formData: Record<string, unknown>): FormProperty {
const newProperty = this.formPropertyFactory.createProperty(
deepCopy(this.schema.items!),
deepCopy(this.ui.$items),
formData,
this as PropertyGroup
) as ObjectProperty;
(this.properties as FormProperty[]).push(newProperty);
return newProperty;
}
private resetProperties(formDatas: Array<Record<string, unknown>>): void {
for (const item of formDatas) {
const property = this.addProperty(item);
property.resetValue(item, true);
}
}
private clearErrors(property?: FormProperty): void {
(property || this)._objErrors = {};
}
// #region actions
add(formData: Record<string, unknown>): FormProperty {
const newProperty = this.addProperty(formData);
newProperty.resetValue(formData, false);
return newProperty;
}
remove(index: number): void {
const list = this.properties as FormProperty[];
this.clearErrors();
list.splice(index, 1);
list.forEach((property, idx) => {
property.path = [property.parent!.path, idx].join(SF_SEQ);
this.clearErrors(property);
// TODO: 受限于 sf 的设计思路,对于移除数组项需要重新对每个子项进行校验,防止错误被父级合并后引起始终是错误的现象
if (property instanceof ObjectProperty) {
property.forEachChild(p => {
p.updateValueAndValidity({ emitValueEvent: false });
});
}
});
if (list.length === 0) {
this.updateValueAndValidity();
}
}
// #endregion
}