@yibozhang/pro-table 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -55
- package/bundles/yibozhang-pro-table.umd.js +420 -374
- package/bundles/yibozhang-pro-table.umd.js.map +1 -1
- package/bundles/yibozhang-pro-table.umd.min.js +1 -1
- package/bundles/yibozhang-pro-table.umd.min.js.map +1 -1
- package/esm2015/lib/components/colmuns-setting/colmuns-setting.component.js +1 -1
- package/esm2015/lib/components/dynamic-search-field/dynamic-search-field.component.js +1 -1
- package/esm2015/lib/constants.js +1 -1
- package/esm2015/lib/page-container/page-container.component.js +1 -1
- package/esm2015/lib/page-container/page-container.module.js +1 -1
- package/esm2015/lib/page-public/antd-form.js +35 -360
- package/esm2015/lib/page-public/array-form.js +340 -0
- package/esm2015/lib/plate-input/plate-input.component.js +1 -1
- package/esm2015/lib/plate-input/plate-input.module.js +1 -1
- package/esm2015/lib/plate-input/plate-prefix-load.service.js +1 -1
- package/esm2015/lib/pro-table.component.js +1 -1
- package/esm2015/lib/pro-table.module.js +1 -1
- package/esm2015/lib/table-search-bar/table-search-bar-module.js +1 -1
- package/esm2015/lib/table-search-bar/table-search-bar.component.js +1 -1
- package/esm2015/lib/tokens.js +1 -1
- package/esm2015/lib/type.js +1 -1
- package/esm2015/public-api.js +4 -2
- package/esm2015/yibozhang-pro-table.js +1 -1
- package/fesm2015/yibozhang-pro-table.js +374 -360
- package/fesm2015/yibozhang-pro-table.js.map +1 -1
- package/lib/components/colmuns-setting/colmuns-setting.component.d.ts.map +1 -1
- package/lib/components/dynamic-search-field/dynamic-search-field.component.d.ts.map +1 -1
- package/lib/constants.d.ts.map +1 -1
- package/lib/page-container/page-container.component.d.ts.map +1 -1
- package/lib/page-container/page-container.module.d.ts.map +1 -1
- package/lib/page-public/antd-form.d.ts +1 -20
- package/lib/page-public/antd-form.d.ts.map +1 -1
- package/lib/page-public/array-form.d.ts +96 -0
- package/lib/page-public/array-form.d.ts.map +1 -0
- package/lib/plate-input/plate-input.component.d.ts.map +1 -1
- package/lib/plate-input/plate-input.module.d.ts.map +1 -1
- package/lib/plate-input/plate-prefix-load.service.d.ts.map +1 -1
- package/lib/pro-table.component.d.ts.map +1 -1
- package/lib/pro-table.module.d.ts.map +1 -1
- package/lib/table-search-bar/table-search-bar-module.d.ts.map +1 -1
- package/lib/table-search-bar/table-search-bar.component.d.ts.map +1 -1
- package/lib/tokens.d.ts.map +1 -1
- package/lib/type.d.ts.map +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +4 -2
- package/public-api.d.ts.map +1 -1
- package/yibozhang-pro-table.d.ts.map +1 -1
- package/yibozhang-pro-table.metadata.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { __awaiter
|
|
1
|
+
import { __awaiter } from 'tslib';
|
|
2
2
|
import { InjectionToken, EventEmitter, Component, Optional, Inject, Input, Output, ContentChild, ContentChildren, TemplateRef, NgModule, forwardRef, ChangeDetectorRef, ElementRef, ViewChild, ComponentFactoryResolver, ViewContainerRef, Injectable, ɵɵdefineInjectable, ɵɵinject } from '@angular/core';
|
|
3
3
|
import { isEqual, hasIn, cloneDeep, isNil, debounce } from 'lodash-es';
|
|
4
4
|
import { isObservable } from 'rxjs';
|
|
5
5
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
|
6
6
|
import { CommonModule } from '@angular/common';
|
|
7
7
|
import { HttpClientModule, HttpClient } from '@angular/common/http';
|
|
8
|
-
import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR,
|
|
8
|
+
import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR, FormGroup, FormBuilder } from '@angular/forms';
|
|
9
9
|
import { RouterModule } from '@angular/router';
|
|
10
10
|
import { NzButtonModule } from 'ng-zorro-antd/button';
|
|
11
11
|
import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
|
|
@@ -26,6 +26,7 @@ import { NzAutocompleteModule } from 'ng-zorro-antd/auto-complete';
|
|
|
26
26
|
import { NzInputNumberModule } from 'ng-zorro-antd/input-number';
|
|
27
27
|
import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
|
|
28
28
|
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
29
|
+
import { v4 } from 'uuid';
|
|
29
30
|
|
|
30
31
|
const ɵ0 = () => [], ɵ1 = (value) => `${value}`, ɵ2 = (value) => value;
|
|
31
32
|
const PRO_TABLE_DEFAULT_PROPS = {
|
|
@@ -1721,8 +1722,6 @@ class AntdFormService {
|
|
|
1721
1722
|
this.labelAlign = "right";
|
|
1722
1723
|
this.labelObservers = {};
|
|
1723
1724
|
this.errorMessageStore = {};
|
|
1724
|
-
this.formArrayConfigStore = {};
|
|
1725
|
-
this.INTERNAL_ID_FIELD = "__formItemId";
|
|
1726
1725
|
this.classPrefix = "ant-form-";
|
|
1727
1726
|
this.defaultErrorMessages = {
|
|
1728
1727
|
required: "该字段为必填项",
|
|
@@ -1733,41 +1732,18 @@ class AntdFormService {
|
|
|
1733
1732
|
};
|
|
1734
1733
|
}
|
|
1735
1734
|
// ==================== 表单创建和初始化 ====================
|
|
1736
|
-
//
|
|
1735
|
+
// 初始化表单
|
|
1737
1736
|
createFormGroup(name, config, options) {
|
|
1738
1737
|
const groupConfig = {};
|
|
1739
1738
|
this.errorMessageStore[name] = {};
|
|
1740
|
-
Object.entries(config).forEach(([key,
|
|
1739
|
+
Object.entries(config).forEach(([key, fieldConfig]) => {
|
|
1741
1740
|
var _a, _b, _c;
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
this.
|
|
1748
|
-
itemConfig: field.itemConfig,
|
|
1749
|
-
uniqueIdField: field.uniqueIdField,
|
|
1750
|
-
};
|
|
1751
|
-
const formArray = this.createFormArrayFromConfig(name, key, field.itemConfig, field.initialItems || [], field.uniqueIdField);
|
|
1752
|
-
groupConfig[key] = formArray;
|
|
1753
|
-
// 存储 FormArray 字段的错误消息配置,格式:arrayName[].fieldName
|
|
1754
|
-
if (field.errorMessages) {
|
|
1755
|
-
Object.entries(field.errorMessages).forEach(([fieldName, errorMessages]) => {
|
|
1756
|
-
const errorMessageKey = `${key}[].${fieldName}`;
|
|
1757
|
-
this.errorMessageStore[name][errorMessageKey] = errorMessages;
|
|
1758
|
-
});
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
else {
|
|
1762
|
-
// 普通字段配置
|
|
1763
|
-
const fieldConfig = field;
|
|
1764
|
-
groupConfig[key] = [
|
|
1765
|
-
{ value: fieldConfig.value, disabled: (_a = fieldConfig.disabled) !== null && _a !== void 0 ? _a : false },
|
|
1766
|
-
(_c = (_b = fieldConfig.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfig)) !== null && _c !== void 0 ? _c : [],
|
|
1767
|
-
];
|
|
1768
|
-
if (fieldConfig.errorMessages) {
|
|
1769
|
-
this.errorMessageStore[name][key] = fieldConfig.errorMessages;
|
|
1770
|
-
}
|
|
1741
|
+
groupConfig[key] = [
|
|
1742
|
+
{ value: fieldConfig.value, disabled: (_a = fieldConfig.disabled) !== null && _a !== void 0 ? _a : false },
|
|
1743
|
+
(_c = (_b = fieldConfig.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfig)) !== null && _c !== void 0 ? _c : [],
|
|
1744
|
+
];
|
|
1745
|
+
if (fieldConfig.errorMessages) {
|
|
1746
|
+
this.errorMessageStore[name][key] = fieldConfig.errorMessages;
|
|
1771
1747
|
}
|
|
1772
1748
|
});
|
|
1773
1749
|
if (options === null || options === void 0 ? void 0 : options.labelWidth) {
|
|
@@ -1810,17 +1786,13 @@ class AntdFormService {
|
|
|
1810
1786
|
result.success = false;
|
|
1811
1787
|
return result;
|
|
1812
1788
|
}
|
|
1813
|
-
// 2. 初始化 errorMessageStore
|
|
1789
|
+
// 2. 初始化 errorMessageStore(如果不存在)
|
|
1814
1790
|
if (!this.errorMessageStore[formName]) {
|
|
1815
1791
|
this.errorMessageStore[formName] = {};
|
|
1816
1792
|
}
|
|
1817
|
-
if (!this.formArrayConfigStore[formName]) {
|
|
1818
|
-
this.formArrayConfigStore[formName] = {};
|
|
1819
|
-
}
|
|
1820
1793
|
// 3. 批量构建控件配置
|
|
1821
1794
|
const controlsToAdd = {};
|
|
1822
1795
|
const errorMessagesToAdd = {};
|
|
1823
|
-
const formArrayConfigsToAdd = {};
|
|
1824
1796
|
// 4. 遍历所有字段配置,进行验证和构建
|
|
1825
1797
|
Object.entries(fieldsConfig).forEach(([fieldName, fieldConfig]) => {
|
|
1826
1798
|
var _a, _b, _c, _d, _e;
|
|
@@ -1835,40 +1807,19 @@ class AntdFormService {
|
|
|
1835
1807
|
(_a = options === null || options === void 0 ? void 0 : options.onFieldAdded) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, false, error);
|
|
1836
1808
|
return;
|
|
1837
1809
|
}
|
|
1838
|
-
// 4.2
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
uniqueIdField: fieldConfig.uniqueIdField,
|
|
1847
|
-
};
|
|
1848
|
-
// 存储错误消息
|
|
1849
|
-
if (fieldConfig.errorMessages) {
|
|
1850
|
-
Object.entries(fieldConfig.errorMessages).forEach(([itemFieldName, errorMessages]) => {
|
|
1851
|
-
const errorMessageKey = `${fieldName}[].${itemFieldName}`;
|
|
1852
|
-
errorMessagesToAdd[errorMessageKey] = errorMessages;
|
|
1853
|
-
});
|
|
1854
|
-
}
|
|
1810
|
+
// 4.2 创建控件
|
|
1811
|
+
const controlOptions = {
|
|
1812
|
+
validators: (_c = (_b = fieldConfig.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfig)) !== null && _c !== void 0 ? _c : [],
|
|
1813
|
+
};
|
|
1814
|
+
const control = this.fb.control(fieldConfig.value, controlOptions);
|
|
1815
|
+
// 设置 disabled 状态
|
|
1816
|
+
if (fieldConfig.disabled) {
|
|
1817
|
+
control.disable();
|
|
1855
1818
|
}
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
validators: (_c = (_b = fieldConfigTyped.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfigTyped)) !== null && _c !== void 0 ? _c : [],
|
|
1861
|
-
};
|
|
1862
|
-
const control = this.fb.control(fieldConfigTyped.value, controlOptions);
|
|
1863
|
-
// 设置 disabled 状态
|
|
1864
|
-
if (fieldConfigTyped.disabled) {
|
|
1865
|
-
control.disable();
|
|
1866
|
-
}
|
|
1867
|
-
controlsToAdd[fieldName] = control;
|
|
1868
|
-
// 存储错误消息
|
|
1869
|
-
if (fieldConfigTyped.errorMessages) {
|
|
1870
|
-
errorMessagesToAdd[fieldName] = fieldConfigTyped.errorMessages;
|
|
1871
|
-
}
|
|
1819
|
+
controlsToAdd[fieldName] = control;
|
|
1820
|
+
// 存储错误消息
|
|
1821
|
+
if (fieldConfig.errorMessages) {
|
|
1822
|
+
errorMessagesToAdd[fieldName] = fieldConfig.errorMessages;
|
|
1872
1823
|
}
|
|
1873
1824
|
result.added.push(fieldName);
|
|
1874
1825
|
(_d = options === null || options === void 0 ? void 0 : options.onFieldAdded) === null || _d === void 0 ? void 0 : _d.call(options, fieldName, true);
|
|
@@ -1891,11 +1842,7 @@ class AntdFormService {
|
|
|
1891
1842
|
Object.entries(errorMessagesToAdd).forEach(([key, messages]) => {
|
|
1892
1843
|
this.errorMessageStore[formName][key] = messages;
|
|
1893
1844
|
});
|
|
1894
|
-
// 7.
|
|
1895
|
-
Object.entries(formArrayConfigsToAdd).forEach(([fieldName, config]) => {
|
|
1896
|
-
this.formArrayConfigStore[formName][fieldName] = config;
|
|
1897
|
-
});
|
|
1898
|
-
// 8. 更新表单验证状态
|
|
1845
|
+
// 7. 更新表单验证状态
|
|
1899
1846
|
if (options === null || options === void 0 ? void 0 : options.updateValueAndValidity) {
|
|
1900
1847
|
formGroup.updateValueAndValidity({
|
|
1901
1848
|
emitEvent: (_a = options === null || options === void 0 ? void 0 : options.emitEvent) !== null && _a !== void 0 ? _a : true,
|
|
@@ -1931,7 +1878,6 @@ class AntdFormService {
|
|
|
1931
1878
|
// 2. 批量收集需要清理的信息
|
|
1932
1879
|
const fieldsToRemove = [];
|
|
1933
1880
|
const errorMessageKeysToRemove = [];
|
|
1934
|
-
const formArrayFields = [];
|
|
1935
1881
|
// 3. 验证每个字段并收集信息
|
|
1936
1882
|
fieldNames.forEach((fieldName) => {
|
|
1937
1883
|
var _a;
|
|
@@ -1945,22 +1891,8 @@ class AntdFormService {
|
|
|
1945
1891
|
(_a = options === null || options === void 0 ? void 0 : options.onFieldRemoved) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, false, error);
|
|
1946
1892
|
return;
|
|
1947
1893
|
}
|
|
1948
|
-
//
|
|
1949
|
-
|
|
1950
|
-
formArrayFields.push(fieldName);
|
|
1951
|
-
// 收集 FormArray 相关的错误消息键(格式:arrayName[].fieldName)
|
|
1952
|
-
if (this.errorMessageStore[formName]) {
|
|
1953
|
-
Object.keys(this.errorMessageStore[formName]).forEach((key) => {
|
|
1954
|
-
if (key.startsWith(`${fieldName}[].`)) {
|
|
1955
|
-
errorMessageKeysToRemove.push(key);
|
|
1956
|
-
}
|
|
1957
|
-
});
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
else {
|
|
1961
|
-
// 普通字段的错误消息键
|
|
1962
|
-
errorMessageKeysToRemove.push(fieldName);
|
|
1963
|
-
}
|
|
1894
|
+
// 收集错误消息键
|
|
1895
|
+
errorMessageKeysToRemove.push(fieldName);
|
|
1964
1896
|
fieldsToRemove.push(fieldName);
|
|
1965
1897
|
});
|
|
1966
1898
|
// 4. 批量执行删除操作
|
|
@@ -1978,12 +1910,6 @@ class AntdFormService {
|
|
|
1978
1910
|
delete this.errorMessageStore[formName][key];
|
|
1979
1911
|
});
|
|
1980
1912
|
}
|
|
1981
|
-
// 4.3 批量删除 FormArray 配置
|
|
1982
|
-
if (this.formArrayConfigStore[formName]) {
|
|
1983
|
-
formArrayFields.forEach((fieldName) => {
|
|
1984
|
-
delete this.formArrayConfigStore[formName][fieldName];
|
|
1985
|
-
});
|
|
1986
|
-
}
|
|
1987
1913
|
}
|
|
1988
1914
|
catch (error) {
|
|
1989
1915
|
// 如果批量删除过程中出错,标记为失败
|
|
@@ -2003,7 +1929,7 @@ class AntdFormService {
|
|
|
2003
1929
|
result.success = result.failed.length === 0;
|
|
2004
1930
|
return result;
|
|
2005
1931
|
}
|
|
2006
|
-
//
|
|
1932
|
+
// 局部赋值
|
|
2007
1933
|
patchFormValues(name, values, options) {
|
|
2008
1934
|
var _a;
|
|
2009
1935
|
const formGroup = this.formStore[name];
|
|
@@ -2011,23 +1937,9 @@ class AntdFormService {
|
|
|
2011
1937
|
console.warn(`[AntdFormService] patchFormValues: form "${name}" not found.`);
|
|
2012
1938
|
return;
|
|
2013
1939
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
const control = formGroup.get(key);
|
|
2017
|
-
// 检测是否是 FormArray
|
|
2018
|
-
if (control instanceof FormArray && Array.isArray(value)) {
|
|
2019
|
-
this.patchFormArray(name, key, value);
|
|
2020
|
-
return;
|
|
2021
|
-
}
|
|
2022
|
-
// 普通字段,直接加入
|
|
2023
|
-
processedValues[key] = value;
|
|
1940
|
+
formGroup.patchValue(values, {
|
|
1941
|
+
emitEvent: (_a = options === null || options === void 0 ? void 0 : options.emitEvent) !== null && _a !== void 0 ? _a : true,
|
|
2024
1942
|
});
|
|
2025
|
-
// 处理普通字段
|
|
2026
|
-
if (Object.keys(processedValues).length > 0) {
|
|
2027
|
-
formGroup.patchValue(processedValues, {
|
|
2028
|
-
emitEvent: (_a = options === null || options === void 0 ? void 0 : options.emitEvent) !== null && _a !== void 0 ? _a : true,
|
|
2029
|
-
});
|
|
2030
|
-
}
|
|
2031
1943
|
}
|
|
2032
1944
|
// 表单校验(自动过滤内部字段)
|
|
2033
1945
|
validateForm(name, options) {
|
|
@@ -2037,12 +1949,12 @@ class AntdFormService {
|
|
|
2037
1949
|
return this.excludeInternalFields(rawValue);
|
|
2038
1950
|
}
|
|
2039
1951
|
else {
|
|
2040
|
-
//
|
|
1952
|
+
// 递归校验所有控件
|
|
2041
1953
|
this.markAllControlsAsDirty(this.formStore[name], (_a = options === null || options === void 0 ? void 0 : options.emitEvent) !== null && _a !== void 0 ? _a : true, (_b = options === null || options === void 0 ? void 0 : options.onlySelf) !== null && _b !== void 0 ? _b : false);
|
|
2042
1954
|
return false;
|
|
2043
1955
|
}
|
|
2044
1956
|
}
|
|
2045
|
-
// 递归标记所有无效控件为 dirty
|
|
1957
|
+
// 递归标记所有无效控件为 dirty
|
|
2046
1958
|
markAllControlsAsDirty(control, emitEvent, onlySelf) {
|
|
2047
1959
|
if (control.invalid) {
|
|
2048
1960
|
control.markAsDirty();
|
|
@@ -2057,15 +1969,9 @@ class AntdFormService {
|
|
|
2057
1969
|
this.markAllControlsAsDirty(childControl, emitEvent, onlySelf);
|
|
2058
1970
|
});
|
|
2059
1971
|
}
|
|
2060
|
-
// 如果是 FormArray,递归处理数组中的每一项
|
|
2061
|
-
if (control instanceof FormArray) {
|
|
2062
|
-
control.controls.forEach((childControl) => {
|
|
2063
|
-
this.markAllControlsAsDirty(childControl, emitEvent, onlySelf);
|
|
2064
|
-
});
|
|
2065
|
-
}
|
|
2066
1972
|
}
|
|
2067
1973
|
// ==================== 错误消息相关 ====================
|
|
2068
|
-
//
|
|
1974
|
+
// 获取字段首条错误提示
|
|
2069
1975
|
getFieldErrorMessage(name, controlName) {
|
|
2070
1976
|
var _a;
|
|
2071
1977
|
const formGroup = this.formStore[name];
|
|
@@ -2081,16 +1987,8 @@ class AntdFormService {
|
|
|
2081
1987
|
if (!control.errors) {
|
|
2082
1988
|
return "";
|
|
2083
1989
|
}
|
|
2084
|
-
// 解析 controlName,支持 FormArray 格式:arrayName.index.fieldName
|
|
2085
|
-
let errorMessageKey = controlName;
|
|
2086
|
-
const arrayMatch = controlName.match(/^(.+)\.(\d+)\.(.+)$/);
|
|
2087
|
-
if (arrayMatch) {
|
|
2088
|
-
// FormArray 格式:arrayName.index.fieldName -> 使用 arrayName[].fieldName 作为 key
|
|
2089
|
-
const [, arrayName, , fieldName] = arrayMatch;
|
|
2090
|
-
errorMessageKey = `${arrayName}[].${fieldName}`;
|
|
2091
|
-
}
|
|
2092
1990
|
// 从 errorMessageStore 获取错误消息配置
|
|
2093
|
-
const errorMessages = (_a = this.errorMessageStore[name]) === null || _a === void 0 ? void 0 : _a[
|
|
1991
|
+
const errorMessages = (_a = this.errorMessageStore[name]) === null || _a === void 0 ? void 0 : _a[controlName];
|
|
2094
1992
|
const mergedMessages = Object.assign(Object.assign({}, this.defaultErrorMessages), (errorMessages !== null && errorMessages !== void 0 ? errorMessages : {}));
|
|
2095
1993
|
for (const errorKey of Object.keys(control.errors)) {
|
|
2096
1994
|
const message = mergedMessages[errorKey];
|
|
@@ -2172,227 +2070,6 @@ class AntdFormService {
|
|
|
2172
2070
|
this.labelObservers[name] = observer;
|
|
2173
2071
|
}
|
|
2174
2072
|
// ==================== 私有方法 ====================
|
|
2175
|
-
// 获取 FormArray
|
|
2176
|
-
getFormArray(formName, arrayName) {
|
|
2177
|
-
const formGroup = this.formStore[formName];
|
|
2178
|
-
if (!formGroup) {
|
|
2179
|
-
console.warn(`[AntdFormService] getFormArray: form "${formName}" not found.`);
|
|
2180
|
-
return null;
|
|
2181
|
-
}
|
|
2182
|
-
const control = formGroup.get(arrayName);
|
|
2183
|
-
if (!control || !(control instanceof FormArray)) {
|
|
2184
|
-
console.warn(`[AntdFormService] getFormArray: array "${arrayName}" not found in form "${formName}".`);
|
|
2185
|
-
return null;
|
|
2186
|
-
}
|
|
2187
|
-
return control;
|
|
2188
|
-
}
|
|
2189
|
-
// 判断是否是 FormArray 配置
|
|
2190
|
-
isFormArrayConfig(field) {
|
|
2191
|
-
return field.type === "array";
|
|
2192
|
-
}
|
|
2193
|
-
// 从配置创建 FormArray
|
|
2194
|
-
createFormArrayFromConfig(formName, arrayName, itemConfig, initialItems, uniqueIdField) {
|
|
2195
|
-
const formArray = this.fb.array([]);
|
|
2196
|
-
initialItems.forEach((item) => {
|
|
2197
|
-
const itemGroup = this.createItemFormGroup(itemConfig, item, uniqueIdField);
|
|
2198
|
-
formArray.push(itemGroup);
|
|
2199
|
-
});
|
|
2200
|
-
return formArray;
|
|
2201
|
-
}
|
|
2202
|
-
// 生成内部ID(使用业务唯一字段或生成临时ID)
|
|
2203
|
-
generateInternalId(itemData, uniqueIdField) {
|
|
2204
|
-
// 优先使用业务唯一字段
|
|
2205
|
-
if (uniqueIdField && (itemData === null || itemData === void 0 ? void 0 : itemData[uniqueIdField]) !== undefined) {
|
|
2206
|
-
const businessId = itemData[uniqueIdField];
|
|
2207
|
-
if (businessId !== null &&
|
|
2208
|
-
businessId !== undefined &&
|
|
2209
|
-
businessId !== "") {
|
|
2210
|
-
return `business-${uniqueIdField}-${businessId}`;
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
// 如果没有业务ID,生成临时ID(用于新添加的项)
|
|
2214
|
-
return `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2215
|
-
}
|
|
2216
|
-
// 创建单个项的 FormGroup
|
|
2217
|
-
createItemFormGroup(itemConfig, itemData, uniqueIdField) {
|
|
2218
|
-
const groupConfig = {};
|
|
2219
|
-
// 添加内部ID字段
|
|
2220
|
-
const itemId = this.generateInternalId(itemData, uniqueIdField);
|
|
2221
|
-
groupConfig[this.INTERNAL_ID_FIELD] = [
|
|
2222
|
-
{ value: itemId, disabled: true },
|
|
2223
|
-
[],
|
|
2224
|
-
];
|
|
2225
|
-
// 添加业务字段
|
|
2226
|
-
Object.entries(itemConfig).forEach(([key, field]) => {
|
|
2227
|
-
var _a, _b, _c;
|
|
2228
|
-
// itemConfig 中的字段应该是 FieldConfig,不应该包含 FormArrayConfig
|
|
2229
|
-
if (this.isFormArrayConfig(field)) {
|
|
2230
|
-
console.warn(`[AntdFormService] createItemFormGroup: FormArrayConfig is not allowed in itemConfig. Skipping field "${key}".`);
|
|
2231
|
-
return;
|
|
2232
|
-
}
|
|
2233
|
-
const fieldConfig = field;
|
|
2234
|
-
const value = (itemData === null || itemData === void 0 ? void 0 : itemData[key]) !== undefined ? itemData[key] : fieldConfig.value;
|
|
2235
|
-
groupConfig[key] = [
|
|
2236
|
-
{ value: value, disabled: (_a = fieldConfig.disabled) !== null && _a !== void 0 ? _a : false },
|
|
2237
|
-
(_c = (_b = fieldConfig.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfig)) !== null && _c !== void 0 ? _c : [],
|
|
2238
|
-
];
|
|
2239
|
-
});
|
|
2240
|
-
return this.fb.group(groupConfig);
|
|
2241
|
-
}
|
|
2242
|
-
// 通过业务唯一字段查找内部ID
|
|
2243
|
-
findFormArrayItemIdByBusinessField(formName, arrayName, uniqueIdField, businessIdValue) {
|
|
2244
|
-
const formArray = this.getFormArray(formName, arrayName);
|
|
2245
|
-
if (!formArray)
|
|
2246
|
-
return null;
|
|
2247
|
-
for (let i = 0; i < formArray.length; i++) {
|
|
2248
|
-
const item = formArray.at(i);
|
|
2249
|
-
const itemValue = item.getRawValue();
|
|
2250
|
-
const internalId = itemValue[this.INTERNAL_ID_FIELD];
|
|
2251
|
-
// 检查内部ID是否匹配业务ID
|
|
2252
|
-
if (internalId && internalId.startsWith(`business-${uniqueIdField}-`)) {
|
|
2253
|
-
const idInInternalId = internalId.replace(`business-${uniqueIdField}-`, "");
|
|
2254
|
-
if (String(idInInternalId) === String(businessIdValue)) {
|
|
2255
|
-
return internalId;
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
// 也检查当前业务字段值是否匹配(处理业务ID更新的情况)
|
|
2259
|
-
if (itemValue[uniqueIdField] === businessIdValue) {
|
|
2260
|
-
return internalId;
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
return null;
|
|
2264
|
-
}
|
|
2265
|
-
// 通过内部ID查找项
|
|
2266
|
-
findFormArrayItemById(formName, arrayName, itemId) {
|
|
2267
|
-
var _a;
|
|
2268
|
-
const formArray = this.getFormArray(formName, arrayName);
|
|
2269
|
-
if (!formArray)
|
|
2270
|
-
return null;
|
|
2271
|
-
for (let i = 0; i < formArray.length; i++) {
|
|
2272
|
-
const item = formArray.at(i);
|
|
2273
|
-
const id = (_a = item.get(this.INTERNAL_ID_FIELD)) === null || _a === void 0 ? void 0 : _a.value;
|
|
2274
|
-
if (id === itemId) {
|
|
2275
|
-
return { index: i, formGroup: item };
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
return null;
|
|
2279
|
-
}
|
|
2280
|
-
// 获取操作类型(必须明确指定 action 字段)
|
|
2281
|
-
getOperationType(itemData) {
|
|
2282
|
-
if (!itemData || typeof itemData !== "object")
|
|
2283
|
-
return null;
|
|
2284
|
-
const action = itemData.action;
|
|
2285
|
-
if (action === "delete" || action === "update" || action === "create") {
|
|
2286
|
-
return action;
|
|
2287
|
-
}
|
|
2288
|
-
return null;
|
|
2289
|
-
}
|
|
2290
|
-
// 过滤操作字段(action 字段不保存到表单中)
|
|
2291
|
-
filterOperationFields(itemData) {
|
|
2292
|
-
if (!itemData || typeof itemData !== "object")
|
|
2293
|
-
return itemData;
|
|
2294
|
-
const filtered = {};
|
|
2295
|
-
Object.entries(itemData).forEach(([key, value]) => {
|
|
2296
|
-
if (key !== "action") {
|
|
2297
|
-
filtered[key] = value;
|
|
2298
|
-
}
|
|
2299
|
-
});
|
|
2300
|
-
return filtered;
|
|
2301
|
-
}
|
|
2302
|
-
// 处理 FormArray 的更新(统一根据 action 字段判断操作类型)
|
|
2303
|
-
patchFormArray(formName, arrayName, newValues) {
|
|
2304
|
-
var _a;
|
|
2305
|
-
const formArray = this.getFormArray(formName, arrayName);
|
|
2306
|
-
if (!formArray) {
|
|
2307
|
-
console.warn(`[AntdFormService] patchFormArray: array "${arrayName}" not found in form "${formName}".`);
|
|
2308
|
-
return;
|
|
2309
|
-
}
|
|
2310
|
-
const config = (_a = this.formArrayConfigStore[formName]) === null || _a === void 0 ? void 0 : _a[arrayName];
|
|
2311
|
-
if (!config) {
|
|
2312
|
-
console.warn(`[AntdFormService] patchFormArray: config not found for array "${arrayName}" in form "${formName}".`);
|
|
2313
|
-
return;
|
|
2314
|
-
}
|
|
2315
|
-
const { itemConfig, uniqueIdField } = config;
|
|
2316
|
-
// 统一根据 action 字段判断操作类型
|
|
2317
|
-
const itemsToDelete = new Set();
|
|
2318
|
-
const itemsToUpdate = new Map();
|
|
2319
|
-
const itemsToAdd = [];
|
|
2320
|
-
newValues.forEach((itemData) => {
|
|
2321
|
-
if (!itemData || typeof itemData !== "object")
|
|
2322
|
-
return;
|
|
2323
|
-
const operationType = this.getOperationType(itemData);
|
|
2324
|
-
if (!operationType) {
|
|
2325
|
-
console.warn(`[AntdFormService] patchFormArray: Item missing required "action" field. Skipping.`, itemData);
|
|
2326
|
-
return;
|
|
2327
|
-
}
|
|
2328
|
-
// 删除操作
|
|
2329
|
-
if (operationType === "delete") {
|
|
2330
|
-
if (uniqueIdField && itemData[uniqueIdField] !== undefined) {
|
|
2331
|
-
const businessId = itemData[uniqueIdField];
|
|
2332
|
-
const internalId = this.findFormArrayItemIdByBusinessField(formName, arrayName, uniqueIdField, businessId);
|
|
2333
|
-
if (internalId) {
|
|
2334
|
-
itemsToDelete.add(internalId);
|
|
2335
|
-
}
|
|
2336
|
-
else {
|
|
2337
|
-
console.warn(`[AntdFormService] patchFormArray: Cannot delete item with ${uniqueIdField}=${businessId}, item not found.`);
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
else {
|
|
2341
|
-
console.warn(`[AntdFormService] patchFormArray: Cannot delete item, missing required uniqueIdField "${uniqueIdField}".`);
|
|
2342
|
-
}
|
|
2343
|
-
return;
|
|
2344
|
-
}
|
|
2345
|
-
// 更新操作
|
|
2346
|
-
if (operationType === "update") {
|
|
2347
|
-
if (uniqueIdField && itemData[uniqueIdField] !== undefined) {
|
|
2348
|
-
const businessId = itemData[uniqueIdField];
|
|
2349
|
-
const internalId = this.findFormArrayItemIdByBusinessField(formName, arrayName, uniqueIdField, businessId);
|
|
2350
|
-
if (internalId) {
|
|
2351
|
-
const filteredData = this.filterOperationFields(itemData);
|
|
2352
|
-
itemsToUpdate.set(internalId, filteredData);
|
|
2353
|
-
}
|
|
2354
|
-
else {
|
|
2355
|
-
console.warn(`[AntdFormService] patchFormArray: Cannot update item with ${uniqueIdField}=${businessId}, item not found. Skipping.`);
|
|
2356
|
-
}
|
|
2357
|
-
}
|
|
2358
|
-
else {
|
|
2359
|
-
console.warn(`[AntdFormService] patchFormArray: Cannot update item, missing required uniqueIdField "${uniqueIdField}". Skipping.`);
|
|
2360
|
-
}
|
|
2361
|
-
return;
|
|
2362
|
-
}
|
|
2363
|
-
// 创建操作
|
|
2364
|
-
if (operationType === "create") {
|
|
2365
|
-
const filteredData = this.filterOperationFields(itemData);
|
|
2366
|
-
itemsToAdd.push(filteredData);
|
|
2367
|
-
}
|
|
2368
|
-
});
|
|
2369
|
-
// 执行删除(需要从后往前删除,避免索引变化)
|
|
2370
|
-
const deleteIndices = [];
|
|
2371
|
-
itemsToDelete.forEach((itemId) => {
|
|
2372
|
-
const found = this.findFormArrayItemById(formName, arrayName, itemId);
|
|
2373
|
-
if (found) {
|
|
2374
|
-
deleteIndices.push(found.index);
|
|
2375
|
-
}
|
|
2376
|
-
});
|
|
2377
|
-
deleteIndices
|
|
2378
|
-
.sort((a, b) => b - a)
|
|
2379
|
-
.forEach((index) => {
|
|
2380
|
-
formArray.removeAt(index);
|
|
2381
|
-
});
|
|
2382
|
-
// 执行更新
|
|
2383
|
-
itemsToUpdate.forEach((itemData, itemId) => {
|
|
2384
|
-
const found = this.findFormArrayItemById(formName, arrayName, itemId);
|
|
2385
|
-
if (found) {
|
|
2386
|
-
const _a = itemData, _b = this.INTERNAL_ID_FIELD, _ = _a[_b], dataToUpdate = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
|
2387
|
-
found.formGroup.patchValue(dataToUpdate);
|
|
2388
|
-
}
|
|
2389
|
-
});
|
|
2390
|
-
// 执行添加
|
|
2391
|
-
itemsToAdd.forEach((itemData) => {
|
|
2392
|
-
const newItem = this.createItemFormGroup(itemConfig, itemData, uniqueIdField);
|
|
2393
|
-
formArray.push(newItem);
|
|
2394
|
-
});
|
|
2395
|
-
}
|
|
2396
2073
|
// 过滤内部字段(递归处理对象和数组)
|
|
2397
2074
|
excludeInternalFields(value) {
|
|
2398
2075
|
if (value === null || value === undefined) {
|
|
@@ -2406,8 +2083,8 @@ class AntdFormService {
|
|
|
2406
2083
|
}
|
|
2407
2084
|
const filtered = {};
|
|
2408
2085
|
Object.entries(value).forEach(([key, val]) => {
|
|
2409
|
-
// 过滤以 __
|
|
2410
|
-
if (!key.startsWith("__")
|
|
2086
|
+
// 过滤以 __ 开头的内部字段
|
|
2087
|
+
if (!key.startsWith("__")) {
|
|
2411
2088
|
filtered[key] = this.excludeInternalFields(val);
|
|
2412
2089
|
}
|
|
2413
2090
|
});
|
|
@@ -2436,6 +2113,343 @@ AntdFormService.ctorParameters = () => [
|
|
|
2436
2113
|
{ type: FormBuilder }
|
|
2437
2114
|
];
|
|
2438
2115
|
|
|
2116
|
+
/** 数组型数据收集基础服务 */
|
|
2117
|
+
class ArrayFormService {
|
|
2118
|
+
constructor() {
|
|
2119
|
+
this.formStore = {};
|
|
2120
|
+
}
|
|
2121
|
+
/** 深度克隆值 */
|
|
2122
|
+
cloneValue(value) {
|
|
2123
|
+
if (value === null || value === undefined) {
|
|
2124
|
+
return value;
|
|
2125
|
+
}
|
|
2126
|
+
if (Array.isArray(value)) {
|
|
2127
|
+
return value.map((item) => this.cloneValue(item));
|
|
2128
|
+
}
|
|
2129
|
+
if (typeof value === "object") {
|
|
2130
|
+
const cloned = {};
|
|
2131
|
+
for (const key of Object.keys(value)) {
|
|
2132
|
+
cloned[key] = this.cloneValue(value[key]);
|
|
2133
|
+
}
|
|
2134
|
+
return cloned;
|
|
2135
|
+
}
|
|
2136
|
+
return value;
|
|
2137
|
+
}
|
|
2138
|
+
/** 比较两个值是否相等 */
|
|
2139
|
+
isEqual(a, b) {
|
|
2140
|
+
if (a === b)
|
|
2141
|
+
return true;
|
|
2142
|
+
if (a === null || b === null)
|
|
2143
|
+
return a === b;
|
|
2144
|
+
if (a === undefined || b === undefined)
|
|
2145
|
+
return a === b;
|
|
2146
|
+
if (typeof a !== typeof b)
|
|
2147
|
+
return false;
|
|
2148
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
2149
|
+
if (a.length !== b.length)
|
|
2150
|
+
return false;
|
|
2151
|
+
return a.every((item, index) => this.isEqual(item, b[index]));
|
|
2152
|
+
}
|
|
2153
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
2154
|
+
const keysA = Object.keys(a);
|
|
2155
|
+
const keysB = Object.keys(b);
|
|
2156
|
+
if (keysA.length !== keysB.length)
|
|
2157
|
+
return false;
|
|
2158
|
+
return keysA.every((key) => this.isEqual(a[key], b[key]));
|
|
2159
|
+
}
|
|
2160
|
+
return false;
|
|
2161
|
+
}
|
|
2162
|
+
/** 创建行的初始值快照 */
|
|
2163
|
+
createRowSnapshot(row, fields) {
|
|
2164
|
+
const snapshot = {};
|
|
2165
|
+
fields.forEach((field) => {
|
|
2166
|
+
snapshot[field.name] = this.cloneValue(row[field.name]);
|
|
2167
|
+
});
|
|
2168
|
+
return snapshot;
|
|
2169
|
+
}
|
|
2170
|
+
/** 初始化数组数据,添加 uid 和 isEdit 字段 */
|
|
2171
|
+
initializeData(data) {
|
|
2172
|
+
return data.map((item) => this.enrichRow(item));
|
|
2173
|
+
}
|
|
2174
|
+
/** 为单行数据添加 uid 和 isEdit 字段 */
|
|
2175
|
+
enrichRow(row) {
|
|
2176
|
+
return Object.assign(Object.assign({}, row), { uid: row.uid || v4(), isEdit: row.isEdit !== undefined ? row.isEdit : false, disabled: row.disabled !== undefined ? row.disabled : false });
|
|
2177
|
+
}
|
|
2178
|
+
/** 新增一行数据 */
|
|
2179
|
+
addRow(data, defaultValues) {
|
|
2180
|
+
const newRow = Object.assign(Object.assign({}, defaultValues), { uid: v4(), isEdit: true, isAdd: true, disabled: false });
|
|
2181
|
+
data.push(newRow);
|
|
2182
|
+
return newRow;
|
|
2183
|
+
}
|
|
2184
|
+
/** 校验单个字段 */
|
|
2185
|
+
validateField(row, fieldName, config) {
|
|
2186
|
+
const fieldConfig = config.fields.find((f) => f.name === fieldName);
|
|
2187
|
+
if (!fieldConfig) {
|
|
2188
|
+
return "";
|
|
2189
|
+
}
|
|
2190
|
+
if (fieldConfig.validator) {
|
|
2191
|
+
return fieldConfig.validator(row[fieldName], row, fieldName);
|
|
2192
|
+
}
|
|
2193
|
+
return "";
|
|
2194
|
+
}
|
|
2195
|
+
/** 校验整行数据 */
|
|
2196
|
+
validateRow(row, config) {
|
|
2197
|
+
const results = {};
|
|
2198
|
+
config.fields.forEach((fieldConfig) => {
|
|
2199
|
+
results[fieldConfig.name] = this.validateField(row, fieldConfig.name, config);
|
|
2200
|
+
});
|
|
2201
|
+
return results;
|
|
2202
|
+
}
|
|
2203
|
+
/** 校验整个数组 */
|
|
2204
|
+
validateData(data, config) {
|
|
2205
|
+
const results = {};
|
|
2206
|
+
data.forEach((row) => {
|
|
2207
|
+
results[row.uid] = this.validateRow(row, config);
|
|
2208
|
+
});
|
|
2209
|
+
return results;
|
|
2210
|
+
}
|
|
2211
|
+
/** 注册表单到存储 */
|
|
2212
|
+
registerForm(formName, data, config) {
|
|
2213
|
+
const initializedData = this.initializeData(data);
|
|
2214
|
+
// 记录初始值快照
|
|
2215
|
+
const initialSnapshot = {};
|
|
2216
|
+
initializedData.forEach((row) => {
|
|
2217
|
+
initialSnapshot[row.uid] = this.createRowSnapshot(row, config.fields);
|
|
2218
|
+
});
|
|
2219
|
+
this.formStore[formName] = {
|
|
2220
|
+
data: initializedData,
|
|
2221
|
+
config,
|
|
2222
|
+
validationResults: {},
|
|
2223
|
+
initialSnapshot,
|
|
2224
|
+
editingSnapshot: {},
|
|
2225
|
+
allTouched: false,
|
|
2226
|
+
rowTouched: {},
|
|
2227
|
+
};
|
|
2228
|
+
// 如果配置了自动更新,立即更新一次
|
|
2229
|
+
this.autoUpdateArrayReference(formName);
|
|
2230
|
+
}
|
|
2231
|
+
/** 从存储中获取表单 */
|
|
2232
|
+
getForm(formName) {
|
|
2233
|
+
return this.formStore[formName];
|
|
2234
|
+
}
|
|
2235
|
+
/** 从存储中获取表单数据 */
|
|
2236
|
+
getFormData(formName) {
|
|
2237
|
+
const form = this.formStore[formName];
|
|
2238
|
+
if (!form) {
|
|
2239
|
+
return undefined;
|
|
2240
|
+
}
|
|
2241
|
+
return form.data.map((item) => {
|
|
2242
|
+
delete item.isEdit;
|
|
2243
|
+
delete item.isAdd;
|
|
2244
|
+
delete item.uid;
|
|
2245
|
+
return item;
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
/** 向表单添加行 */
|
|
2249
|
+
addRowToForm(formName, defaultValues) {
|
|
2250
|
+
const form = this.formStore[formName];
|
|
2251
|
+
if (!form) {
|
|
2252
|
+
return undefined;
|
|
2253
|
+
}
|
|
2254
|
+
const newRow = this.addRow(form.data, defaultValues);
|
|
2255
|
+
// 为新行记录初始值快照
|
|
2256
|
+
form.initialSnapshot[newRow.uid] = this.createRowSnapshot(newRow, form.config.fields);
|
|
2257
|
+
// 自动更新外部数组引用
|
|
2258
|
+
this.autoUpdateArrayReference(formName);
|
|
2259
|
+
return newRow;
|
|
2260
|
+
}
|
|
2261
|
+
/** 校验表单,自动标记所有字段为已触碰 */
|
|
2262
|
+
validateForm(formName) {
|
|
2263
|
+
const form = this.formStore[formName];
|
|
2264
|
+
if (!form) {
|
|
2265
|
+
return true;
|
|
2266
|
+
}
|
|
2267
|
+
// 标记所有字段为已触碰
|
|
2268
|
+
form.allTouched = true;
|
|
2269
|
+
const results = this.validateData(form.data, form.config);
|
|
2270
|
+
form.validationResults = results;
|
|
2271
|
+
// 检查是否有任何错误
|
|
2272
|
+
for (const uid of Object.keys(results)) {
|
|
2273
|
+
for (const fieldName of Object.keys(results[uid])) {
|
|
2274
|
+
if (results[uid][fieldName]) {
|
|
2275
|
+
return false;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
return true;
|
|
2280
|
+
}
|
|
2281
|
+
/** 开启编辑模式,保存快照用于取消恢复 */
|
|
2282
|
+
enableEdit(formName, row) {
|
|
2283
|
+
const form = this.formStore[formName];
|
|
2284
|
+
if (form && row.uid) {
|
|
2285
|
+
// 保存编辑前的快照
|
|
2286
|
+
form.editingSnapshot[row.uid] = this.createRowSnapshot(row, form.config.fields);
|
|
2287
|
+
}
|
|
2288
|
+
row.isEdit = true;
|
|
2289
|
+
}
|
|
2290
|
+
/** 取消编辑,恢复到编辑前的数据 */
|
|
2291
|
+
disableEdit(formName, row) {
|
|
2292
|
+
const form = this.formStore[formName];
|
|
2293
|
+
if (form && row.uid && form.editingSnapshot[row.uid]) {
|
|
2294
|
+
// 恢复编辑前的数据
|
|
2295
|
+
const snapshot = form.editingSnapshot[row.uid];
|
|
2296
|
+
form.config.fields.forEach((field) => {
|
|
2297
|
+
row[field.name] = this.cloneValue(snapshot[field.name]);
|
|
2298
|
+
});
|
|
2299
|
+
// 更新初始快照为恢复后的值,消除 touched 状态
|
|
2300
|
+
form.initialSnapshot[row.uid] = this.cloneValue(snapshot);
|
|
2301
|
+
// 清理编辑快照和 touched 状态
|
|
2302
|
+
delete form.editingSnapshot[row.uid];
|
|
2303
|
+
delete form.rowTouched[row.uid];
|
|
2304
|
+
// 清理该行的校验结果
|
|
2305
|
+
if (form.validationResults) {
|
|
2306
|
+
delete form.validationResults[row.uid];
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
row.isEdit = false;
|
|
2310
|
+
}
|
|
2311
|
+
/** 确认编辑,保留修改后的数据 */
|
|
2312
|
+
confirmEdit(formName, row) {
|
|
2313
|
+
const form = this.formStore[formName];
|
|
2314
|
+
if (form && row.uid) {
|
|
2315
|
+
// 清理编辑快照(保留当前数据)
|
|
2316
|
+
if (form.editingSnapshot[row.uid]) {
|
|
2317
|
+
delete form.editingSnapshot[row.uid];
|
|
2318
|
+
}
|
|
2319
|
+
// 更新初始快照为当前值(用于后续 touched 检测)
|
|
2320
|
+
form.initialSnapshot[row.uid] = this.createRowSnapshot(row, form.config.fields);
|
|
2321
|
+
// 清除 touched 状态,基于新的 initialSnapshot 重新判断
|
|
2322
|
+
delete form.rowTouched[row.uid];
|
|
2323
|
+
}
|
|
2324
|
+
row.isEdit = false;
|
|
2325
|
+
row.isAdd = false;
|
|
2326
|
+
}
|
|
2327
|
+
/** 从表单中删除指定行 */
|
|
2328
|
+
deleteRowFromForm(formName, row) {
|
|
2329
|
+
const form = this.formStore[formName];
|
|
2330
|
+
if (!form || !row.uid) {
|
|
2331
|
+
return false;
|
|
2332
|
+
}
|
|
2333
|
+
const index = form.data.findIndex((item) => item.uid === row.uid);
|
|
2334
|
+
if (index === -1) {
|
|
2335
|
+
return false;
|
|
2336
|
+
}
|
|
2337
|
+
form.data.splice(index, 1);
|
|
2338
|
+
// 清理该行的所有快照、touched 状态和校验结果
|
|
2339
|
+
delete form.initialSnapshot[row.uid];
|
|
2340
|
+
delete form.editingSnapshot[row.uid];
|
|
2341
|
+
delete form.rowTouched[row.uid];
|
|
2342
|
+
if (form.validationResults) {
|
|
2343
|
+
delete form.validationResults[row.uid];
|
|
2344
|
+
}
|
|
2345
|
+
// 自动更新外部数组引用
|
|
2346
|
+
this.autoUpdateArrayReference(formName);
|
|
2347
|
+
return true;
|
|
2348
|
+
}
|
|
2349
|
+
/** 检测字段是否已被触碰 */
|
|
2350
|
+
isFieldTouched(form, row, fieldName) {
|
|
2351
|
+
var _a;
|
|
2352
|
+
// 整个表单已 touched(整个表单提交时)
|
|
2353
|
+
if (form.allTouched) {
|
|
2354
|
+
return true;
|
|
2355
|
+
}
|
|
2356
|
+
// 当前行已 touched(单行保存时)
|
|
2357
|
+
if (form.rowTouched[row.uid]) {
|
|
2358
|
+
return true;
|
|
2359
|
+
}
|
|
2360
|
+
// 检测当前值与初始值是否不同
|
|
2361
|
+
const initialValue = (_a = form.initialSnapshot[row.uid]) === null || _a === void 0 ? void 0 : _a[fieldName];
|
|
2362
|
+
const currentValue = row[fieldName];
|
|
2363
|
+
return !this.isEqual(initialValue, currentValue);
|
|
2364
|
+
}
|
|
2365
|
+
/** 校验指定行的指定字段,未修改时不显示校验状态 */
|
|
2366
|
+
validateFieldInRow(formName, row, fieldName) {
|
|
2367
|
+
const form = this.formStore[formName];
|
|
2368
|
+
if (!form) {
|
|
2369
|
+
return "";
|
|
2370
|
+
}
|
|
2371
|
+
const fieldConfig = form.config.fields.find((f) => f.name === fieldName);
|
|
2372
|
+
if (!fieldConfig) {
|
|
2373
|
+
return "";
|
|
2374
|
+
}
|
|
2375
|
+
// 执行校验
|
|
2376
|
+
let result = "";
|
|
2377
|
+
if (fieldConfig.validator) {
|
|
2378
|
+
result = fieldConfig.validator(row[fieldName], row, fieldName);
|
|
2379
|
+
}
|
|
2380
|
+
// 更新校验结果存储
|
|
2381
|
+
if (!form.validationResults) {
|
|
2382
|
+
form.validationResults = {};
|
|
2383
|
+
}
|
|
2384
|
+
if (!form.validationResults[row.uid]) {
|
|
2385
|
+
form.validationResults[row.uid] = {};
|
|
2386
|
+
}
|
|
2387
|
+
form.validationResults[row.uid][fieldName] = result;
|
|
2388
|
+
// 如果字段未被触碰,不显示校验状态
|
|
2389
|
+
if (!this.isFieldTouched(form, row, fieldName)) {
|
|
2390
|
+
return "";
|
|
2391
|
+
}
|
|
2392
|
+
return result ? "error" : "success";
|
|
2393
|
+
}
|
|
2394
|
+
/** 获取指定行指定字段的校验错误信息 */
|
|
2395
|
+
getFieldErrorMessage(formName, row, fieldName) {
|
|
2396
|
+
var _a, _b;
|
|
2397
|
+
const form = this.formStore[formName];
|
|
2398
|
+
if (!form || !row.uid) {
|
|
2399
|
+
return "";
|
|
2400
|
+
}
|
|
2401
|
+
// 如果字段未被触碰,不显示错误信息
|
|
2402
|
+
if (!this.isFieldTouched(form, row, fieldName)) {
|
|
2403
|
+
return "";
|
|
2404
|
+
}
|
|
2405
|
+
return ((_b = (_a = form.validationResults) === null || _a === void 0 ? void 0 : _a[row.uid]) === null || _b === void 0 ? void 0 : _b[fieldName]) || "";
|
|
2406
|
+
}
|
|
2407
|
+
/** 校验指定行的所有字段 */
|
|
2408
|
+
validateRowAllFields(formName, row) {
|
|
2409
|
+
const form = this.formStore[formName];
|
|
2410
|
+
if (!form || !row.uid) {
|
|
2411
|
+
return true;
|
|
2412
|
+
}
|
|
2413
|
+
// 更新初始快照为当前值
|
|
2414
|
+
form.initialSnapshot[row.uid] = this.createRowSnapshot(row, form.config.fields);
|
|
2415
|
+
// 标记当前行为 touched(只影响当前行,不影响其他行)
|
|
2416
|
+
form.rowTouched[row.uid] = true;
|
|
2417
|
+
let hasError = false;
|
|
2418
|
+
form.config.fields.forEach((fieldConfig) => {
|
|
2419
|
+
const result = this.validateFieldInRow(formName, row, fieldConfig.name);
|
|
2420
|
+
if (result === "error") {
|
|
2421
|
+
hasError = true;
|
|
2422
|
+
}
|
|
2423
|
+
});
|
|
2424
|
+
return !hasError;
|
|
2425
|
+
}
|
|
2426
|
+
/** 自动更新外部数组引用 */
|
|
2427
|
+
autoUpdateArrayReference(formName) {
|
|
2428
|
+
const form = this.formStore[formName];
|
|
2429
|
+
if (!form || !form.config.targetObject || !form.config.arrayPropertyName) {
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
const newArray = form.data ? [...form.data] : [];
|
|
2433
|
+
// 更新目标对象的数组属性为新数组引用
|
|
2434
|
+
form.config.targetObject[form.config.arrayPropertyName] = newArray;
|
|
2435
|
+
}
|
|
2436
|
+
/** 是否有正在编辑的行 */
|
|
2437
|
+
hasEditingRow(formName) {
|
|
2438
|
+
const form = this.formStore[formName];
|
|
2439
|
+
if (!form) {
|
|
2440
|
+
return false;
|
|
2441
|
+
}
|
|
2442
|
+
return form.data.some((item) => item.isEdit);
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
ArrayFormService.ɵprov = ɵɵdefineInjectable({ factory: function ArrayFormService_Factory() { return new ArrayFormService(); }, token: ArrayFormService, providedIn: "root" });
|
|
2446
|
+
ArrayFormService.decorators = [
|
|
2447
|
+
{ type: Injectable, args: [{
|
|
2448
|
+
providedIn: "root",
|
|
2449
|
+
},] }
|
|
2450
|
+
];
|
|
2451
|
+
ArrayFormService.ctorParameters = () => [];
|
|
2452
|
+
|
|
2439
2453
|
/*
|
|
2440
2454
|
* Public API Surface of pro-table
|
|
2441
2455
|
*/
|
|
@@ -2444,5 +2458,5 @@ AntdFormService.ctorParameters = () => [
|
|
|
2444
2458
|
* Generated bundle index. Do not edit.
|
|
2445
2459
|
*/
|
|
2446
2460
|
|
|
2447
|
-
export { AntdFormService, DefaultPlatePrefixLoadService, PLATE_PREFIX_LOAD_SERVICE, PRO_TABLE_COLUMN_REMOTE, PRO_TABLE_DEFAULT_COLUMN, PRO_TABLE_DEFAULT_PROPS, PlateInputModule, ProTableComponent, ProTableModule, ɵ0, ɵ1, ɵ2, PageContainerModule as ɵa, PageContainerComponent as ɵb, TableSearchBarModule as ɵc, TableSearchBarComponent as ɵd, PlateInputComponent as ɵe, ColmunsSettingComponent as ɵf, DynamicSearchFieldComponent as ɵg };
|
|
2461
|
+
export { AntdFormService, ArrayFormService, DefaultPlatePrefixLoadService, PLATE_PREFIX_LOAD_SERVICE, PRO_TABLE_COLUMN_REMOTE, PRO_TABLE_DEFAULT_COLUMN, PRO_TABLE_DEFAULT_PROPS, PlateInputModule, ProTableComponent, ProTableModule, ɵ0, ɵ1, ɵ2, PageContainerModule as ɵa, PageContainerComponent as ɵb, TableSearchBarModule as ɵc, TableSearchBarComponent as ɵd, PlateInputComponent as ɵe, ColmunsSettingComponent as ɵf, DynamicSearchFieldComponent as ɵg };
|
|
2448
2462
|
//# sourceMappingURL=yibozhang-pro-table.js.map
|