From eebf45eb03eabaa63298a00a38ff0c2462d17573 Mon Sep 17 00:00:00 2001 From: Erik Lumme Date: Wed, 13 Sep 2017 13:18:56 +0300 Subject: [PATCH] Migrate DynamicallyUpdatingStateBeforeSendingChangesToClient --- ...StateBeforeSendingChangesToClient.asciidoc | 85 +++++++++++++++++++ documentation/articles/contents.asciidoc | 1 + 2 files changed, 86 insertions(+) create mode 100644 documentation/articles/DynamicallyUpdatingStateBeforeSendingChangesToClient.asciidoc diff --git a/documentation/articles/DynamicallyUpdatingStateBeforeSendingChangesToClient.asciidoc b/documentation/articles/DynamicallyUpdatingStateBeforeSendingChangesToClient.asciidoc new file mode 100644 index 0000000000..ee8fc7967e --- /dev/null +++ b/documentation/articles/DynamicallyUpdatingStateBeforeSendingChangesToClient.asciidoc @@ -0,0 +1,85 @@ +[[dynamically-updating-state-before-sending-changes-to-client]] +Dynamically updating state before sending changes to client +----------------------------------------------------------- + +There are some cases where a server-side implementation must delay some +work until right before data is about to be sent to the client. Some +examples of this: + +* An expensive operation that should be done only once and not every +time some input for the calculation changes. +* Anything that depends on the component (or extension) being attached +to the component hierarchy. + +Vaadin provides the `ClientConnector.beforeClientResponse(boolean +initial)` method, which a server-side component or extension can override +if it wants to make some final adjustments to its shared state or send +some RPC right before data is being sent to the client. Because the +method is called just before the data will be sent, there are some +special considerations: + +* You should remember to call `super.beforeClientResponse(initial)` +because e.g. `AbstractComponent` relies on the method for performing its +own last minute changes to the state. +* The component hierarchy may not be modified in the +`beforeClientResponse` method, doing so might cause undesirable side +effects. +* `markAsDirty()` has no effect - changes will only be sent for connectors +that were marked as dirty before `beforeClientResponse` was called. + +Please note that `beforeClientResponse` will only be called for components +that the framework thinks might have changes, e.g. because they have +recently been attached, their `getState()` method has been called or they +have been marked as dirty using `markAsDirty()`. + +This shows a simple example where two terms are summed together only +once even if the terms are changed multiple times before a response is +sent to the client. + +[source,java] +.... +public class Addition extends AbstractComponent { + private int term1; + private int term2; + private boolean needsRecalculation = false; + + public void setTerm1(int value1) { + this.term1 = value1; + needsRecalculation = true; + + //Mark the component as dirty to ensure beforeClientResponse will be invoked + markAsDirty(); + } + + public void setTerm2(int value2) { + this.term2 = value2; + needsRecalculation = true; + + //Mark the component as dirty to ensure beforeClientResponse will be invoked + markAsDirty(); + } + + private int calculateSum() { + return term1 + term2; + } + + @Override + public void beforeClientResponse(boolean initial) { + super.beforeClientResponse(initial); + if (needsRecalculation) { + needsRecalculation = false; + // This could be an expensive operation that we don't want to do every time setTerm1 or setTerm2 is invoked. + getState().sum = calculateSum(); + } + } + + @Override + protected AddResultState getState() { + return (AddResultState) super.getState(); + } +} + +class AddResultState extends ComponentState { + public int sum; +} +.... diff --git a/documentation/articles/contents.asciidoc b/documentation/articles/contents.asciidoc index 1df8e59c25..009bd03820 100644 --- a/documentation/articles/contents.asciidoc +++ b/documentation/articles/contents.asciidoc @@ -81,4 +81,5 @@ are great, too. - link:CreatingAComponentExtension.asciidoc[Creating a component extension] - link:CreatingAUIExtension.asciidoc[Creating a UI extension] - link:UsingDeclarativeServices.asciidoc[Using declarative services] +- link:DynamicallyUpdatingStateBeforeSendingChangesToClient.asciidoc[Dynamically updating state before sending changes to client] - link:CreatingAThemeUsingSass.asciidoc[Creating a theme using Sass] -- 2.39.5