breeze EntityManager:如何附加普通的javascript对象

时间:2014-10-31 16:02:55

标签: breeze

我有从客户端调用的自定义OData操作。此操作的结果是一个JSON对象列表,需要作为实体合并回Breeze缓存中。如何将JSON对象转换为Breeze实体并将该实体合并回entityManager的缓存中?一些代码:

   $http.post('/odata/MyEntityType/MyCustomAction/', {
                    'someData': JSON.stringify(element1),
                    'SomeOtherData': JSON.stringify(element2)
                })
                .success(function (results) {
                    //results.value is an array of *MyEntityType* JSON objects.   `//Is there a way to convert these to breeze entities?`

                    });

我尝试过的一些事情:

  

manager.importEntities(" MyEntityType",theJsonForAnEntity); //只是在黑暗中刺伤

     

manager.createEntity(" MyEntityType",theJsonForAnEntity); //错误:'禁止'的MergeStrategy当具有相同密钥的实体已附加"

时,不允许您附加实体

2 个答案:

答案 0 :(得分:2)

createEntity无效

对不起,杰里米,但那不行。这是一个测试,显示原因:

// Failing test
test("merge customer date into existing cached entity using `createEntity`", function () {
    var em = newEm();

    // Create an unchanged entity in cache as if it had been queried
    em.createEntity('Customer', {
        CustomerID: dummyCustID,
        CompanyName: 'Foo Co',
        ContactName: 'Ima Kiddin'
    }, UNCHGD);  // creates the entity in the Unchanged state

    // Try to merge some changes into that entity using createEntity.
    var changes = {
        CustomerID: dummyCustID,
        CompanyName: 'Bar Co',
    }
    var cust = em.createEntity('Customer', changes, 
                   UNCHGD, breeze.MergeStrategy.OverwriteChanges);

    ok(cust.entityAspect.entityState.isUnchanged(), "cust should be 'Unchanged'");

    // using Knockout; it's simpler if using Angular
    equal(cust.CompanyName(), 'Bar Co', "Company name should be updated by merge'");
    equal(cust.ContactName(), 'Ima Kiddin', "Contact name should be unchanged after merge'");
});

第三个断言失败,因为createEntity方法会覆盖每个属性,而不仅仅是感兴趣的一个数据值(在这种情况下为CompanyName)。这意味着ContactName为空。

importEntities无效

出于同样的原因。导入实体时,导入整个实体,而不仅仅导入其中的一部分。这样也会消灭此示例中的ContactName

手动合并

我认为如果您希望将结果与缓存中的实体混合,您必须手动执行此操作。您将不得不迭代结果并更新缓存的等效项。

想象一下,上面的changes变量是POST的结果。以下测试确实通过了:

// Passing test
test("merge customer date into existing cached entity", function () {
    var em = newEm();

    // Create an unchanged entity in cache as if it had been queried
    em.createEntity('Customer', {
        CustomerID: dummyCustID,
        CompanyName: 'Foo Co',
        ContactName: 'Ima Kiddin'
    }, UNCHGD);  // creates the entity in the Unchanged state

    // Merge some changes into that entity
    // Imagine that `changes` came from your server as a result of your POST
    var changes = {
        CustomerID: dummyCustID,
        CompanyName: 'Bar Co',
    }

    // First find the customer in cache.
    // Here I'm assuming it will always be there; you should be careful
    var cust = em.getEntityByKey('Customer', changes.CustomerID);

    // using Knockout; it's a little simpler in Angular
    for (var p in changes) { cust[p](changes[p]); }

    cust.entityAspect.setUnchanged(); // cuz the previous updates changed the state to "Modified"

    ok(cust.entityAspect.entityState.isUnchanged(), "cust should be 'Unchanged'");
    equal(cust.CompanyName(), 'Bar Co', "Company name should be updated by merge'");
    equal(cust.ContactName(), 'Ima Kiddin', "Contact name should be unchanged after merge'");
});

功能请求

我可以想象一下Breeze可以通过所有适当的错误检查为您自动化的未来。如果您认为这样的“JSON实体合并”功能对Breeze来说是一个有价值的增强功能,请将其添加到User Voice。我会很快同意,但除非人们想要,否则我们无法添加功能。

答案 1 :(得分:0)

我认为您使用manager.createEntity方法处理某些事情。尝试指定合并策略(默认为"不允许"这会导致您的用例出现问题):

manager.createEntity("MyEntityType", thePocoEntityFromTheCustomODataAction, breeze.MergeStrategy.PreserveChanges);

合并策略:http://www.breezejs.com/sites/all/apidocs/classes/MergeStrategy.html

createEntity:http://www.breezejs.com/sites/all/apidocs/classes/EntityManager.html#method_createEntity