javascript - Vaadin 的 AbstractJavascriptComponent 的部分状态更改

标签 javascript vaadin vaadin7

我正在实现一个基于 JavaScript 的 Vaadin 组件,它需要显示和更新一个相对较大的数据集。我通过扩展 AbstractJavaScriptComponent 来做到这一点。

我试图让 JS 端尽可能“愚蠢”,使用 RPC 将用户交互委托(delegate)给服务器,并更新共享状态。然后使用新状态调用 JS 连接器包装器的 onStateChange 函数,这会导致 DOM 相应地更新。

我有两个问题:

  1. 我不想在每次更新一小部分时都传输整个数据集。
  2. 我也不想每次都完全重建 UI。

我可以解决第二个问题,方法是保持以前的状态并比较它的各个部分以找出发生了什么变化,然后只进行必要的 DOM 更改。 但这仍然存在第一个问题。

我是否必须停止使用 Vaadin 的共享状态机制,而只使用 RPC 来传达对状态的更改?

更新: 我一直在做一些测试,显然 Vaadin 的共享状态机制在效率方面很糟糕:

每当组件调用 getState() 以更新状态对象中的某些属性(或者甚至不更新任何内容)时,整个 状态对象都会被传输。据我所知,避免这种情况的唯一方法是不使用共享状态机制,而是使用 RPC 调用将特定状态更改传达给客户端。

RPC 方法存在一些需要解决的问题,例如:如果您在单个请求/响应周期内多次更改某个值,您不希望多次进行 RPC 调用。相反,您只想发送最后一个值,就像共享状态机制只在响应中发送最终状态一样。您可以为要单独发送的状态的每个部分保留脏标志(或者只保留先前状态的副本并进行比较),但是您需要以某种方式在请求处理结束时触发 RPC 调用。如何做到这一点?

欢迎提出任何想法!

更新 2:

Vaadin 8 修复了根本问题:它仅发送已更改的状态属性。此外,当仅执行 RPC 调用(并且不更改任何状态)时,它不再调用 JS 连接器上的 onStateChange()

最佳答案

OP 正确地指出共享状态同步对于基于 AbstractJavaScriptComponent 的组件是低效的。每当连接器被标记为脏时,整个状态对象都会被序列化并可供 Javascript 连接器的 onStateChange 方法使用。其他非 JavaScript 组件通过仅发送更改来更智能地处理状态更新。代码中发生这种情况的确切位置是 com.vaadin.server.LegacyCommunicationManager.java

中的第 97 行
boolean supportsDiffState = !JavaScriptConnectorState.class
            .isAssignableFrom(stateType);

我不确定为什么基于 AbstractJavaScriptComponent 的组件的状态更新处理方式不同。也许是为了简化 javascript 连接器并消除从增量中组装完整状态对象的需要。如果可以在未来的版本中解决这个问题,那就太好了。

正如您所建议的,您可以完全放弃 JavaScriptComponentState 并依靠服务器-> 客户端 RPC 进行更新。在您的服务器端组件中保留脏标志,或通过您想要的任何机制比较旧状态和新状态。

要合并更改并为每个更改仅发送一个 RPC 调用,您可以在服务器端组件中覆盖 beforeClientResponse(boolean initial)。这是在向客户端发送响应之前调用的,您有机会添加一组 RPC 调用来更新客户端组件。

或者,您可以覆盖 encodeState,您可以在其中自由地向客户端发送您喜欢的任何 JSON。您可以选择向 super.encodeSate 返回的基本 JSON 对象添加更改列表。您的 javascript 连接器可以在其 onStateChange 方法中进行适当的解释。

编辑添加:在服务器端组件中调用 getState() 会将连接器标记为脏。如果您想获取状态而不将其标记为脏,请改用 getState(false)

关于javascript - Vaadin 的 AbstractJavascriptComponent 的部分状态更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36253541/

相关文章:

java - Vaadin 网格,附加 header 使其他 header 不可见

瓦丁 : How to get Element by ID?

javascript - 我如何为这个庞大的对象列表中的每个对象添加一个额外的键和值

java - 如何获取Vaadin资源路径的URL?

asp.net - 存储数据以供客户端导出。我有一团糟

java - java 或 vaadin 中特定日期到达时显示通知

java - 如何在 Vaadin 中正确验证 DateField?

css - 在 spring boot vaadin 应用程序中使用多个主题

javascript - 在 iPhone Safari 中使用 ScriptProcessorNode

javascript - 如何使用 Javascript 客户端对象模型检索 Sharepoint 2010 列表项权限