我已经ing了几天头。
假设您有一个汽车销售管理应用程序。您出售不同的型号。您的汽车模型有50个属性。仅作为示例,假设您要出售布加迪威龙。现在,您刚刚收到了其中5辆车。因此,我登录到我的应用程序,首先创建具有特定ID的Bugatti Veyron。然后我想添加第二个,但是有一个问题-我将不得不再次写下所有这些属性!我想要一个“复制”按钮,我只想更改序列号,轻而易举的就可以更改ID和voila,那里有两辆车!
出于黑客的考虑,起初我创建了以下解决方案:
newCar(datacontext.createCar());
newCar().property1(oldCar().property1());
newCar().property2(oldCar().property2());
...
这很丑陋,在我证明自己可以做到之后,当然,要求申请的目的是使所有内容都可复制-绝不行!某处必须有副本。在挖掘了很多东西之后,甚至试图在微风中改变某些东西,我也无法做以下事情:
manager.createEntity('Car', oldCar);
现在,最新的解决方案比第一个解决方案更可行,但仍然需要比我想要的更多的代码,并且不够直观:
var newObject = {};
manager.metadataStore._structuralTypeMap[oldCar.entityType.name].dataProperties.forEach(function (singleProperty) {
if (!singleProperty.isPartOfKey)
newObject[singleProperty.name] = oldCar[singleProperty.name];
});
var newCar = manager.createEntity('Equipment', newObject);
是否有其他“更清洁”的方法来制作具有完全相同的属性,但ID不同的新实体?
我应该提到Car实体中有一些ICollections,但是这种有问题的解决方案忽略了可以改进的ICollections,但是目前,我自己通过一些.forEach循环来处理该问题。
我们正在后台处理这种事情。准备就绪时,我们会通知您。没有承诺或时间安排。
同时,我对此付诸行动。我决定利用微风EntityManager.exportEntities
方法知道如何克隆实体这一事实。如果您阅读该方法的微妙源代码,就会知道它很棘手。
这是我想出的(作为平民,而不是Breeze开发人员):
function cloneItem(item) {
// export w/o metadata and then parse the exported string.
var exported = JSON.parse(manager.exportEntities([item], false));
// extract the entity from the export
var type = item.entityType;
var copy = exported.entityGroupMap[type.name].entities[0];
// remove the entityAspect
delete copy.entityAspect;
// remove the key properties
type.keyProperties.forEach(function (p) { delete copy[p.name]; });
// the "copy" provides the initial values for the create
return manager.createEntity(type, copy);
}
像您一样,它保留外键属性,这意味着父源的引用导航属性将具有从缓存中提取的值(如果源具有此值)。
像您一样,将不会填充集合导航属性。此方法不知道如何克隆子代。这也不是不言自明的。这对您来说是额外的功劳。
正如您所问的那样,我已经实现了克隆孩子(集合导航)的功能。我遵循了您建议的语法,因此用法如下:
cloneItem(something, ['collectionProp1', 'collectionProp2']);
请注意,我再次依靠Breeze导出来完成繁重的工作
警告:此代码非常脆弱,并且不能推广到所有型号
function cloneItem(item, collectionNames) {
var manager = item.entityAspect.entityManager;
// export w/o metadata and then parse the exported string.
var exported = JSON.parse(manager.exportEntities([item], false));
// extract the entity from the export
var type = item.entityType;
var copy = exported.entityGroupMap[type.name].entities[0];
// remove the entityAspect (todo: remove complexAspect from nested complex types)
delete copy.entityAspect;
// remove the key properties (assumes key is store-generated)
type.keyProperties.forEach(function (p) { delete copy[p.name]; });
// the "copy" provides the initial values for the create
var newItem = manager.createEntity(type, copy);
if (collectionNames && collectionNames.length) {
// can only handle parent w/ single PK values
var parentKeyValue = newItem.entityAspect.getKey().values[0];
collectionNames.forEach(copyChildren);
}
return newItem;
function copyChildren(navPropName) {
// todo: add much more error handling
var navProp = type.getNavigationProperty(navPropName);
if (navProp.isScalar) return; // only copies collection navigations. Todo: should it throw?
// This method only copies children (dependent entities), not a related parent
// Child (dependent) navigations have inverse FK names, not FK names
var fk = navProp.invForeignKeyNames[0]; // can only handle child w/ single FK value
if (!fk) return;
// Breeze `getProperty` gets values for all model libraries, e.g. both KO and Angular
var children = item.getProperty(navPropName);
if (children.length === 0) return;
// Copy all children
var childType = navProp.entityType;
children = JSON.parse(manager.exportEntities(children, false));
var copies = children.entityGroupMap[childType.name].entities;
copies.forEach(function(c) {
delete c.entityAspect;
// remove key properties (assumes keys are store generated)
childType.keyProperties.forEach(function (p) { delete c[p.name]; });
// set the FK parent of the copy to the new item's PK
c[fk] = parentKeyValue;
// merely creating them will cause Breeze to add them to the parent
manager.createEntity(childType, c);
});
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句