propertyChanged用于服务器计算的属性不再在1.4.12中触发

时间:2014-05-20 08:32:28

标签: breeze

我通过使用propertyChanged事件向最终用户显示服务器计算值。 我正在使用breeze 1.4.8并且我正在使用生产力堆栈(ms sql,web api,ef) 它工作正常。 最近我已经更新到1.4.12,我认识到这个事件不再被解雇了。 该物业" A_ProvisionTotal"只计算服务器端。

<snip>
    var token = vm.transaction.entityAspect.propertyChanged.subscribe(propertyChanged);
    function propertyChanged(propertyChangedArgs) {
        var propertyName = propertyChangedArgs.propertyName;
        if (vm.transaction.tblEmployees.CalculationMethod == "A" && propertyName == "A_ProvisionTotal")
            logSuccess('Provision neuberechnet' + '<br/>' + 'Aktuell: ' + $filter('number')(vm.transaction.Provision, 2), true);
</snip>

如果这是一个已知的回归,如果您需要更多代码段,请告诉我。

3 个答案:

答案 0 :(得分:0)

更新3

这不是一个错误 - 请参阅此帖子的回复,将此描述为记录和故意行为。

2014年6月2日更新

我忽略了你问题中的一个关键事实......在我看到code you included in your comments之后,我才清楚地看到了这一事实。让我为其他读者提取关键部分:

您的测试发出一个查询,然后将不相关的更改保存到服务器(服务器端更新感兴趣的属性),然后检查该指示感兴趣的属性是否会引发propertyChanged保存结果合并回缓存。

var query = EntityQuery.from("Orders").where('id', 'eq', 10248);
query.using(em).execute().then(querySucceeded).then(checkPropertyChanged).fin(start);

// querySucceed receives order 10248, updates an unrelated property (so you can save), 
// wires up a propertyChanged listener and saves, returning the saveChanges promise

function checkPropertyChanged(saveResults) {
    var saved = saveResults.entities[0];

        // this passes because the server-side change to `Freight` was returned
        ok(saved && saved.Freight() === 1200.00,
            "freight got changed serverside");

        // this fails because Breeze did not notify you that the `Freight` had changed
        ok(notifications[0].propertyName  === "Freight",
            "notified serverside change of Freight Property");
}

总结一下,当实体数据重新启用时,您预计服务器上的属性更改会触发客户端上的propertyChanged通知 从服务器检索,作为saveChanges的副产品。

我有这个权利吗?

我们的文档不清楚查询,保存和导入实体结果的合并是否会引发propertyChanged

我在内部讨论并确认这些操作应该引发propertyChanged 。我还编写了另一个(稍微简单)测试,揭示了您发现的错误:合并的保存结果可能不会引发propertyChanged

我们会调查并告诉您我们何时修复它。感谢您的发现。

原始

我们有回归测试,表明在v.1.4.12中引发了Breeze EntityAspect.propertyChanged事件。例如,您可以在DocCode sample, "basicTodoTests.js"中看到它的工作原理;滚动到:&#34; Breeze propertyChanged在任何属性更改时引发&#34;。

你能否确认它真的是微风失败?也许你正在改变的财产实际上并不是一个实体财产?有时您认为您正在更改实体(例如,您的Transaction实体),但您更改的属性实际上并不是实体。那么问题是您认为将映射到Transaction的数据不是......并且您可以开始寻找那个完全不同的问题。

无论如何,我建议你写一个小测试来证实你的怀疑...最重要的是你自己......然后是我们。这将有助于我们从场景中发现您的场景的不同之处。如果你能找到它,我们会修复它。感谢。

答案 1 :(得分:0)

实际上,我不确定这是一个错误。属性更改事件在保存合并期间被触发,但属性名称参数被记录为&#39; null&#39;因为保存而被解雇。

http://www.breezejs.com/sites/all/apidocs/classes/EntityAspect.html#event_propertyChanged

来自&#39; propertyName &#39;的API文档EntityAspect.propertyChanged返回的参数:

已更改的属性的名称。此值将为“空”&#39;用于替换整个实体的操作。这包括需要合并的查询,导入和保存。在这种情况下,其余参数也不存在。

1.4.8和1.4.13之间可能发生的事情是我们实际上更仔细地实施了我们的设计规范,并且可能介绍了您的破坏行为。 (我们应该记录这些但很可能错过了)。

由Ward更新

updated the DocCode test首先确认了您问题中描述的行为,然后确认了记录的行为。

我们感到遗憾的是,我们显然忽略了之前记录的行为,并且我们没有提及发布说明(自更新后)的重大变化。

以下测试:

asyncTest("propertyChanged raised when merged save result changes a property", 3, function () {
    var em = newTodosEm(); 
    var todo = em.createEntity('TodoItem', {Description: "Saved description" });

    em.saveChanges().then(saveSucceeded).catch(handleFail).finally(start);

    ok(todo.entityAspect.isBeingSaved, "new todo is in the act of being saved");

    // This change should be overwritten with the server value when the save result is returned
    // even though the entity is in an Added state and the MergeStrategy is PreserveChanges
    // because save expects to merge server values into an entity it is saving
    todo.Description("Changed on client before save returns");

    var descriptionChanged = false;
    todo.entityAspect.propertyChanged.subscribe(function (changeArgs) {
        // Watch carefully! The subscription is called twice during merge
        // 1) propertyName === "Id" (assigned with permanent ID)
        // 2) propertyName === null (WAT?)  
        // and not called with propertyName === "Description" as you might have thought.
        // Actually 'null' means "merged a lot of properties"
        // Documented: http://www.breezejs.com/sites/all/apidocs/classes/EntityAspect.html#event_propertyChanged
        // The reason for this: don't want to fire a ton of events on whole entity load
        // especially when merging many entities at the same time.
        if (changeArgs.propertyName === null || changeArgs.propertyName === 'Description') {
            descriptionChanged = true;
        }
    });

    function saveSucceeded(saveResult) {
        var saved = saveResult.entities[0];
        // passes
        equal(saved && saved.Description(), "Saved description",
            "the merge after save should have restored the saved description");

        // fails
        ok(descriptionChanged,
            "should have raised propertyChanged after merge/update of 'Description' property");
    }
});

答案 2 :(得分:0)

关于如何实现所需功能的一些想法。

  1. 实体可以记住私有字段中的最后一个计算值。然后,每当触发重新计算时,您可以将新值与最后计算的值进行比较,如果没有更改,则忽略新计算的值。
  2. 或者,您可以将计算中涉及的属性定义为实体ctor函数中的ES5属性,然后在使用新值设置时触发相关属性的setter中的计算。更多信息请访问:http://www.breezejs.com/documentation/extending-entities#es5-property。如果要将计算等行为构建到setter中,ES5属性很方便。