AbstractJavaScriptComponent
来实现这一点。我试图尽量让JS端保持“愚蠢”,将用户交互委托给使用RPC与服务器通信的共享状态,并更新了共享状态。然后JS连接器包装器的
onStateChange
函数被调用以使用新状态更新DOM。我有两个问题:
1.当小部分数据集更新时,我不想每次都传输整个数据集。 2.我也不希望每次都完全重新构建UI。
我可以通过保留先前的状态并比较其部分来解决第二个问题,以找出更改的内容并仅进行必要的DOM更改。但是这仍然存在第一个问题。
我必须停止使用Vaadin的共享状态机制,而只使用RPC来通信变化吗?
更新: 我已经进行了一些测试,它似乎表明Vaadin的共享状态机制在效率方面非常糟糕:
每当组件调用
getState()
以更新状态对象中的某个属性(或者甚至没有更新任何内容),整个状态对象就会被传输。据我所知,避免这种情况的唯一方法是不使用共享状态机制,而是使用RPC调用向客户端通信特定的状态更改。RPC方法存在一些问题需要解决,例如:如果在单个请求/响应周期内多次更改值,则不希望多次进行RPC调用。相反,您只希望像共享状态机制一样仅发送最后一个值作为响应中的最终状态。您可以为要单独发送的每个状态部分保留脏标志(或仅保留先前状态并进行比较),但然后您需要以某种方式触发RPC调用在请求处理结束时。该如何实现?
欢迎提出任何关于这方面的想法!
更新2: Vaadin 8修复了根本问题:它仅发送更改的状态属性。此外,仅在执行RPC调用时(而不更改任何状态)时,它不再调用JS连接器上的
onStateChange()
函数。
onStateChange()
JS 函数),因为AbstractComponent#beforeClientResponse(boolean initial)
重复调用getState()
,将连接器标记为脏。当然,我们可以覆盖,但我相信那段代码存在是有原因的。在我看来,这是一个 Vaadin 的 bug。 - hermangetState()
以调用super.getState(false)
并仅在需要时显式调用markAsDirty()
来解决问题,但发现另一个问题:任何JS函数调用(通过callFunction(...)
)都将调用markAsDirty()
并导致JS连接器的onStateChange()
被调用。已提交另一张工单。 - herman