仅更新实体的一部分

时间:2013-02-22 15:56:48

标签: knockout.js breeze

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

// define the viewmodel
function episodesViewModel() {

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

很棒的问题!

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

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

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

  1. 在服务器上创建一个DTO类(EpisodeSaveDto?),表示要保存的Episode对象的形状。它必须包含Id和您要保存的属性。

  2. 它不会是来自服务器的普通元数据的一部分,因为它不是真正的实体。因此,在BreezeJS客户端上用JavaScript中的元数据描述DTO对象。然后,Breeze会将您的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上下文。

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

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

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