0

我们在Breeze.js中有一个EntityQuery ,它带来了包含在一个实体实例中的数据以及来自相关实体的数据。

数据正确到达客户端。我可以看到来自服务器的响应,也可以在XHR.responseText中看到来自服务器的数据是正确的

但由于某种原因,有时数据无法正确填充结果(即使用可观察对象构建的),可观察对象存在,但它们的值不正确。我明确指出,这只是有时。因为相同的查询没有更改,指向服务器上完全相同的实体实例,有时确实会正确填充结果。

由于在数据未正确解析或填充的情况下,我在 responseText 上看到了正确的数据,因此我实施了一个简单的解决方法/hack 来解决问题,但我想知道是否有其他更好的解决方法

这是查询(出于保密原因,实体名称更改为 Op)和解决方法

        new breeze.EntityQuery('OpsWithRelatedData')
            .where('Id', '==', id)
            .using(self.EntityManager)
            .execute()
            .done(function (r) {
                var op = r.results.pop();

                // This is an ugly hack to prevent a Breeze problem
                // (when it doesn't evaluate to an op correctly)
                var evalOp = eval(r.XHR.responseText)[0];
                if (evalOp.StatusId != op.StatusId()) {
                    viewModel.Op().StatusId(evalOp.StatusId);
                    viewModel.Op().Status().Id(evalOp.Status.Id);
                    viewModel.Op().Status().Name(evalOp.Status.Name);
                } else {
                    viewModel.Op().StatusId(op.StatusId());
                }

                def.resolve(op);
            });

一些附加信息:

  1. 解决方法有效并且已经过测试。
  2. 查询通常有效,但仅在这种情况下,当它在服务器上实体的状态更改后被触发时它不起作用(返回错误的状态 ID),但正确的状态值来自服务器的响应(已检查)。
  3. 所以肯定是客户端解析的问题
  4. 结果总是被填充并且没有错误被抛出(测试添加失败处理程序)。问题是值不正确(并且与响应的 json 中的值不同)。
  5. 从我所看到的猜测,它似乎使用本地存储中的旧版本实体填充结果(???),虽然这看起来很奇怪,因为没有错误并且结果从服务器返回 OK . 而且填充的数据有时甚至与上次执行时的数据不匹配。
  6. 使用Breeze.js 版本 1.3.0会发生这种情况,尽管看起来我们可以测试迁移到当前版本 1.4.8 以查看是否可以解决问题,但我想先知道是否有其他问题修复它并防止像这里指出的问题的方法: Breeze.js parsing XHR.responseText,然后评估我们是否应该尝试任何选项或只是保留解决方法。

有任何想法吗?

4

1 回答 1

0

我不确定,但您描述的行为的最可能原因是查询数据到达时相关实体处于更改状态

您可以通过检查EntityState查询的成功回调中的每个结果实体并在实体处于更改状态时引发相应的诊断警报来对此进行测试。我敢打赌,你会证实我的假设。

Breeze 查询结果基于MergeStrategy. 默认情况下,该策略是“PreserveChanges”,它告诉 Breeze 在目标实体有未决更改时忽略传入的值(即当它EntityState不是“未更改”时)。

我猜您查询的实体“大部分时间”都会更新,因为它们大部分时间都处于“未更改”状态。但有时某些东西——用户,你的应用程序——将实体置于更改状态,而在该状态下,来自服务器的新值会被简单地忽略。

这是预期的行为……这就是“PreserveChanges”的意思……Breeze 没有理由抛出异常。

如果更适合您的用例,您可以更改为MergeStrategy.OverwriteChanges,作为查询默认值或基于每个查询。

就个人而言,我敦促您不要使用该XHR对象。我不明白为什么 Breeze 首先会公开它,并且某些 Breeze AJAX 适配器实现将无法提供该对象。如果我有我的方式,它将在未来的 Breeze 版本中从界面中消失。请将其在 API 中的存在视为无意且不受支持。

于 2014-02-09T06:05:08.310 回答