仅更新实体的一部分

问题描述 投票:1回答:2

我有一个视图模型,它具有通过Breeze检索的实体的observableArray。

// define the viewmodel
function episodesViewModel() {

this.episodes = ko.observableArray();
...
}

每个剧集实体都有一系列属性,我希望在页面加载时完整填充。然后,如何在保存回服务器时和更新时仅更新其中一个属性?其他属性要大得多,并且会保持静止,所以没有必要在线上来回发送它们。

knockout.js breeze
2个回答
0
投票

好问题!

我的第一个问题是“你确定额外'静态属性'的有效负载重量实际上是一个问题吗?”我不得不问你......因为我不得不问自己......因为我倾向于预测问题并过早地解决问题。在测量之后,我发现所有工作和担心对于现场应用来说无关紧要。请原谅我的无礼。

让我们假设您确实遇到了问题。 episode对象非常沉重(可能带有图像数据),你不能将它在你的模型中拆分成EpisodeEpisodeDetail类,它们之间有一对一的关系。你被困在一个胖胖的Epsiode级别。我知道这发生了。只是检查。

你可以做你想做的事。我希望在Breeze中使这个场景更容易。今天有一种“OK”的方式(有些人可能称之为黑客攻击)。我会在这里为你勾勒出它的轮廓。你可以尝试一下......让我们知道如何改进它。

  1. 在服务器上创建一个DTO类(EpisodeSaveDto?),表示要保存的Episode对象的形状。它必须具有Id和您想要保存的属性。
  2. 它不会是来自服务器的普通元数据的一部分,因为它不是真正的实体。因此,在BreezeJS客户端上用JavaScript中的元数据描述DTO对象。然后微风将你的EpisodeSaveDto视为一个实体。有关此技术的示例,请参阅"NoDb" Sample
  3. 创建EpisodeSaveDto的实例并使用您的更改填充它们。您正在更新,而不是添加新实例,因此请使用EntityState-setting signature on the createEntity方法。 var episode = manager.createEntity(“EpisodeDto”,{id:origEpisode.id,foo:changedFooValue},EntityState.Modified);
  4. 在服务器上,在自定义(派生)EFContextProvider中,覆盖BeforeSaveEntities方法。该方法接收按类型排列的已更改实体的字典。
  5. 删除EpisodeSaveDto更改的集合并将它们处理到适当的Episode实体中以进行保存。如果您没有使用EF或SQL Db,那么您将在ContextProvider的实现中执行此操作...再次如"NoDb" Sample中所示。
  6. 将准备保存的Episode实体的集合添加到已更改实体的字典中,并将它们也附加到EF上下文。

服务器上的Breeze.NET将在服务器上保存您制造的Episode实体,并忽略传入的EpisodeSaveDto(它不知道如何保存)。

忏悔:我是从记忆中写出来的,而且在第6步我有点模糊。我相信你明白了。我们有点伪造Breeze.NET了。

正如我在开始时所说,我想让这个场景更容易。我希望看到内置支持“命令”,可以接受和返回实体集。如果您认为我们应该这样做,请将您的投票添加到Breeze User Voice


1
投票

或者,您可以使用带外AJAX调用来传统路线。

添加响应HTTP PATCH的Web API控制器操作方法。你让它做对了。

使用更改的Episode数据从客户端(使用jQuery AJAX或amplify.js)调用它。这是直接的WebAPI / AJAX编程。

如果用户直接对Episode实体进行了更改,则必须根据带外保存的情况进行调整。 EntityManager.getChanges('Episode')将为您提供缓存中更改的Episode实体。保存成功完成后,在回调中你可以调用episode.entityAspect.acceptChanges告诉Breeze EntityManager episode不再处于更改状态。

© www.soinside.com 2019 - 2024. All rights reserved.