首先让我有一个解决方案,但我并不认为它很优雅。所以,我正在寻找一种更清洁的方法来做到这一点。
我在视图面板中显示了EntityProxy。视图面板是仅使用显示模式的RequestFactoryEditorDriver。用户单击数据元素并打开弹出编辑器,以使用比视图面板中显示的数据位数更多的数据来编辑EntityProxy的数据元素。当用户保存元素时,我需要视图面板来更新显示。
我遇到了一个问题,因为弹出编辑器流程的RequestFactoryEditorDriver不允许您访问已编辑的数据。驱动程序使用在用于向服务器发送数据的上下文中传递的相同内容。但是,即使您将其转换为存储在编辑器驱动程序中的上下文类型,从flush返回的上下文也只允许Receiver<Void>
。编辑()调用。 [它似乎也没有发送和EntityProxyChanged事件,所以我无法监听并更新显示视图。 - 抓住这个 - 我现在看到此事件不适用于此用例]
我找到的解决方案是更改我的域对象persist以返回新保存的实体。然后像这样创建弹出编辑器
editor.getSaveButtonClickHandler().addClickHandler(createSaveHandler(driver, editor));
// initialize the Driver and edit the given text.
driver.initialize(rf, editor);
PlayerProfileCtx ctx = rf.playerProfile();
ctx.persist().using(playerProfile).with(driver.getPaths())
.to(new Receiver<PlayerProfileProxy>(){
@Override
public void onSuccess(PlayerProfileProxy profile) {
editor.hide();
playerProfile = profile;
viewDriver.display(playerProfile);
}
});
driver.edit(playerProfile, ctx);
editor.centerAndShow();
然后在保存处理程序中,我只是触发()从flush()获得的上下文。虽然这种方法有效,但似乎并不正确。 [看起来我应该在显示视图中订阅entitychanged事件并从那里更新实体和视图。 - 再次刮擦,与之前的原因相同]此方法也保存了完整的实体,而不仅仅是更改的位,这将增加带宽使用。
我认为应该发生的事情是,当您刷新实体时,应该“乐观地”更新实体的rf托管版本并触发实体代理更改事件。只有在保存中出现问题时才恢复实体。实际保存只应发送更改的位。通过这种方式,无需重新获取整个实体并通过线路两次发送完整数据。
有更好的解决方案吗?
答案 0 :(得分:2)
您似乎并不真正理解RF发生的细节;另外,你的术语并没有真正帮助理解(冲洗与火灾)。
RF中的代理是您检索服务器时状态的快照。您可以使用应用程序中其他位置的实体(通过其他代理)执行任何操作,您的代理将不会更改以反映这些修改。
当服务器检测到它已更改时,在客户端(对于服务器已知且已从客户端发送的实体)调度EntityProxyChange
事件:其版本(由getVersion
上的Locator
返回的已更改,或已被删除(由isLive
的{{1}}方法说明)。如果您不使用Locator
,则会使用该实体的Locator
,getVersion
将被isLive
实体替换为其ID(如已返回)通过find
方法)并检查getId
(这也是null
中isLive
的默认实现。)
在您的情况下,如果您没有看到正在调度Locator
,请检查您是否正确更新了实体的版本。
最后,RF总是将更改的差异发送到服务器(EntityProxyChange
除外,在这种情况下,差异无意义)。至于检索数据,默认情况下它不会检索链接代理,除非您使用ValueProxy
明确要求它们;这与您发送的有关实体的内容无关。
在您的情况下,要更新视图面板,您有3种可能性:
with
事件或弹出窗口中的显式信号;您可以使用代理{{1}的EntityProxyChange
find
方法作为参数,以及您需要的属性的相应RequestContext
你正在做第二个HTTP请求时效率有点低,但另一方面它可以处理应用程序中其他地方的更改(它们也会触发stableId
个事件)with
方法返回已保存的实体,或者在同一个方法中调用EntityProxyChange
方法请求同一HTTP请求中的批处理 save
和find
的上下文。总而言之,我认为我会选择当前的解决方案。关于你的代码,我将使用代理和回调启动弹出窗口,并将请求上下文和编辑编辑器驱动程序保留为弹出窗口的实现细节:你只需要它调用视图面板完成后,将更新的代理作为参数传递给回调。
关于术语的最后一句话:你刷新编辑器驱动程序将字段的值复制回对象/代理,并且(独立地,但在你的情况下顺序)你 fire 一个请求上下文,用于向服务器发送一批服务方法和代理更改。刷新编辑器驱动程序不会向服务器发送任何内容,这些是不同的操作。
答案 1 :(得分:1)
我找到了更好的解决方案。我在调用RequestFactoryEditorDriver edit()之前使代理可编辑,并将可编辑代理保存为我的视图代理。
PlayerProfileCtx ctx = rf.playerProfile();
playerProfile = ctx.edit(playerProfile);
driver.edit(playerProfile, ctx);
另外,(我以为我之前尝试过这个并且它没有用,但我一定做错了)然后我可以转换从flush回来的上下文。 1}}调用发送给驱动程序的上下文是相同的,因此它是安全的。
edit()
这样做解决了rf使用fire()发送整个对象而不仅仅是差异的问题。我不知道为什么会这样。这可能是RF编辑器驱动程序中的错误。
所以现在我已经在视图中获得了驱动程序中的数据,而不必依赖于从服务器发送回来的数据。但我确实注册了EntityProxyChange事件,因此如果服务器上存在冲突,我可以检测并重新获取。