在1.4.12中,服务器计算属性不再触发

  • 本文关键字:属性 计算 不再 服务器 breeze
  • 更新时间 :
  • 英文 :


我通过使用propertyChanged事件向最终用户显示服务器计算值。我使用的是微风1.4.8,我正在使用生产力堆栈(ms sql, web api,等)它工作得很好。最近我更新到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>

让我知道如果这是一个已知的回归,如果你需要更多的片段。

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

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

更新3

这不是一个bug——请参阅对这篇文章的回应,该回复将此描述为一个有文档记录的故意行为。

2014年6月2日更新

我忽略了你问题中的一个关键事实……只有当我看了你在评论中包含的代码后,我才明白了这一点。让我为其他读者摘录其中的关键部分:

您的测试发出一个查询,然后将一个不相关的更改保存到服务器(其中感兴趣的属性在服务器端更新),然后检查当保存结果合并回缓存时,该感兴趣的属性是否引发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示例"basicTodoTests.js";"中看到它的工作原理。

当任何属性发生变化时触发

你能确认这真的是Breeze故障吗?也许您正在更改的属性实际上不是实体属性?有时你认为你正在改变一个实体(例如,你的Transaction实体),但你改变属性的东西实际上不是一个实体。那么问题是,您认为将映射到Transaction的数据不是……你可以开始寻找完全不同的问题。

无论如何,我建议你写一个小测试来证实你的怀疑…对你自己来说最重要的是……然后是我们。这将帮助我们发现你们的方案与我们的方案的不同之处。如果你能找到,我们会修好的。谢谢。

实际上,我不确定这是一个bug。属性更改事件确实在保存合并期间被触发,但属性名称参数在保存时被触发时被记录为'null'。

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

由EntityAspect.propertyChanged:

返回的'propertyName'参数的API文档

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

在1.4.8和1.4.13之间可能发生的事情是,我们实际上更仔细地实现了我们的设计规范,并可能引入了您的破坏行为。(我们应该这样记录,但很可能遗漏了)。

Ward更新

我更新了DocCode测试,首先确认了你问题中描述的行为,然后确认了记录的行为。

我们很遗憾,我们显然忽略了早期实现文档化的行为,并且我们没有在发布说明(更新后)中提到突破性的更改。

这个测试:

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");
    }
});

最新更新