RequestFactoryEditorDriver getting edited data after flush

倾然丶 夕夏残阳落幕 提交于 2019-12-01 10:27:24

You don't seem to really understand the details of what's going on with RF; plus, your terminology doesn't really help in understanding (flush vs. fire).

A proxy in RF is a snapshot of the server's state at the time you retrieved it. You can do whatever you want with the entity elsewhere in your app (through other proxies), your proxy won't ever change to reflect those modifications.

An EntityProxyChange event is dispatched on the client-side (for an entity that is already known by the server and has been sent from the client) when the server has detected that it has changed: either its version (as returned by getVersion on the Locator) has changed, or it has been deleted (as told by the isLive method of the Locator). If you don't use a Locator, it'll use the getVersion of the entity and isLive will be replaced by finding the entity by its ID (as returned by its getId method) and checking for null (this is also the default implementation of isLive in the Locator).
In your case, if you don't see an EntityProxyChange being dispatched, then check that you correctly update the entity's version.

Finally, RF always sends a diff of your changes to the server (except for a ValueProxy, in which case a diff would have no meaning). As for retrieving data, it doesn't retrieve linked proxies by default, unless you explicitly ask for them using with; and this is independent of what you possibly sent about the entity.

In your case, to update the view panel, you have 3 possibilities:

  • retrieve the proxy back from the server (listening to EntityProxyChange events or after an explicit signal from your popup; you could use the find method of RequestContext with the proxy's stableId as argument, and the appropriate with for the properties you need).
    It's a bit inefficient as you're doing a second HTTP request, but on the other hand it can handle changes from elsewhere in your app (they'll fire EntityProxyChange events too)
  • retrieve the updated proxy in the same HTTP request as the one you use to save it: have the save method of your request context return the saved entity, or call the find method in the same request context to batch the save and find together in the same HTTP request.
    That's what you did. It sends a diff of the changes and retrieves the properties needed by your view panel. One could say it has the drawback of tightly coupling your popup and your view panel, it's up to you to decide whether it's an acceptable trade-off.
  • use the entity you edited and sent to the server right in your view panel, with no extra data over the wire.
    While this seems simpler, you'll miss any change that could have been done on the entity by another user (changes only the server know).

All in all, I think I'd go with the current solution. Regarding your code though, I'd launch the popup with the proxy and a callback, and leave the request context and editing editor driver as implementation details of the popup: you only need that it calls the view panel back when it's done, passing the updated proxy as an argument to the callback.

A last word regarding terminology: you flush an editor driver to copy the field's value back to the object/proxy, and (independently, but in your case sequentially) you fire a request context to send a batch of service methods and proxy changes to the server. Flushing an editor driver doesn't send anything to the server, these are distinct actions.

I found a better solution. I make the proxy editable before calling the RequestFactoryEditorDriver edit() and save the editable proxy as my view proxy.

PlayerProfileCtx ctx = rf.playerProfile();
playerProfile = ctx.edit(playerProfile);
driver.edit(playerProfile, ctx);

Also, (and I thought I had tried this before and it didn't work but I must have done something wrong then) I can cast the context that comes back from the flush. It is the same context I sent to the driver with the edit() call so it is safe.

PlayerProfileCtx ctx  = (PlayerProfileCtx) driver.flush();

Doing this fixed the problem with rf sending the whole object with fire() and not just the diffs. I'm not sure why though. That might be a bug in the RF Editor Driver.

So now I have the data from the driver already in the view and don't have to depend on sending it back from the server. But I did register for EntityProxyChange events so I could detect and refetch if there was a conflict on the server.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!