函数支持的操作,用于创建对象的副本



是否可以编写一个TypeScript函数,以编程方式创建对象的副本,而无需对要复制的对象属性的引用进行硬编码?

我正在尝试启用一个用户工作流,在该工作流中,用户有权创建指定对象的副本,即使用Form创建并部分完成一个对象,创建新对象的10倍副本,填写新对象的数据。

我已经成功地创建了一个复制指定对象的Function Backed Action,但所有对被复制属性的引用都是硬编码的,这不太适合维护,也是我们组织的一个相对常见的请求。

所需功能的代码示例:

@OntologyEditFunction()
public GenerticBatchCopyObjects(mySelectedObject: ObjectAPIName, numberNewObjects: Integer): void {
/** Set UUID primary key */
let object_pk = Uuid.random()
for (let i = 1; i <= numberNewObjects; i++) {
/** initialize new object */
const newObject = Objects.create().ObjectAPIName(object_pk + "_" + String(i))
/** copy all properties from selected object record to new object */
for property in mySelectedObject.properties:
if property != "name_of_primary_key_column":
newObject.property = mySelectedObject.property 
}
}

目前还没有一个很好的方法来实现这一点,也可能不建议这样做。这主要是因为在我能看到的任何(漂亮的(方法中,将从对象复制的属性列表在发布/编译时都是固定的。

仅用于复制属性的部分类型安全解决方案

我在下面包含了这个函数的最通用版本,但它有一些局限性。更具体地说,copy函数

  1. 不复制FK属性未表示的链接(即,它只复制属性(
  2. 不适应,当有新的或删除的属性时可能会中断;以及
  3. 不容易维护,因为功能可能会根据编译时间而更改
private isPrimaryKey(x: string): x is MyObjectType["primaryKey"]["apiName"] {
return x === MyObjectType.primaryKey.apiName;
}
@OntologyEditFunction()
public copy(obj: MyObjectType): void {
const new_obj = Objects.create().myObjectType(Uuid.random());
var prop : keyof typeof MyObjectType.properties;
for (prop in MyObjectType.properties) {
if (!this.isPrimaryKey(prop)) {
new_obj[prop] = obj[prop];
}
}
}

用于复制所有内容的显式类型安全解决方案

如果本体发生变化,下面的方法需要更多的手动调整,但明确表示必须根据本体的变化来更改代码。这种方法还复制链接。

同样值得注意的是,这种行为可能不是所需的行为,因为它不会递归地复制链接对象,而是尝试复制链接。请测试这是否给出了所需的结果。

static PROPERTIES = ["myProperty"] as const;
static MULTILINKS = ["myMultiLink"] as const;
static SINGLELINKS = ["mySingleLink", "myOtherSingleLink"] as const;
@OntologyEditFunction()
public copy2(obj: MyObjectType): void {
const new_obj = Objects.create().myObjectType(Uuid.random());
MyFunctions.PROPERTIES.forEach(p => {
new_obj[p] = obj[p];
});
MyFunctions.MULTILINKS.forEach(p => {
obj[p].all().forEach(v => new_obj[p].add(v));
});
MyFunctions.SINGLELINKS.forEach(p => {
const v = obj[p].get();
if (v !== undefined) {
new_obj[p].set(v);
}
});
}

如果您的对象类型没有属性/多链接/单链接以使编译器满意,则可能需要排除一些代码。

最新更新