Preserving Contents of Embedded Applications on Refresh
It’s possible to have embedded applications preserve their contents on refresh, much as one can do with normal Vaadin applications, using the @PreserveOnRefresh
annotation. However, due to the nature of embedded Vaadin applications, there are a few changes to how annotations are used when embedding components.
Using @PreserveOnRefresh When Embedding
In the normal annotation case, the @PreserveOnRefresh
annotation is added to the Component
that the user wants to preserve. When preserving embeddable web components, the @PreserveOnRefresh
annotation is added to the WebComponentExporter
class. The preserving then affects all embedded instances produced by that exporter.
@PreserveOnRefresh
public class EmbeddedComponentExporter
extends WebComponentExporter<EmbeddedComponent> {
public EmbeddedComponentExporter() {
super("embedded-component");
}
@Override
protected void configureInstance(
WebComponent<EmbeddedComponent> webComponent,
EmbeddedComponent component) {
}
}
If you want to have two versions of the web component, one that’s preserved and one that isn’t, you can export the same Component
twice under different tags:
@PreserveOnRefresh
public class EmbeddedComponentExporter1
extends WebComponentExporter<EmbeddedComponent> {
public EmbeddedComponentExporter1() {
super("embedded-component-1");
}
@Override
protected void configureInstance(
WebComponent<EmbeddedComponent> webComponent,
EmbeddedComponent component) {
}
}
public class EmbeddedComponentExporter2
extends WebComponentExporter<EmbeddedComponent> {
public EmbeddedComponentExporter2() {
super("embedded-component-2");
}
@Override
protected void configureInstance(
WebComponent<EmbeddedComponent> webComponent,
EmbeddedComponent component) {
}
}
Preserving Identity of an Embedded Application
Since embedded Vaadin applications live on pages that aren’t themselves usually Vaadin applications, the embedded web component backed by a server-side Vaadin Component
uses a generated ID to link those two facets together. When the custom tag on the client side is upgraded as a Vaadin Web Component and connected to the Component
on the server side, it sends an identifier to the server, so that Vaadin can match the two components.
Each embedded web component generates an identifier for itself, which consists of its tag plus a running counter. For example, two <embedded-component>
web components on a page might have identifiers EmbeddedComponent-0
and EmbeddedComponent-1
. To guarantee that a web component instance is uniquely preserved and its state doesn’t leak to other instances of that web component, the generated ID is combined with the window name, and the state is stored to the user’s session. This enables the storing and restoring of a user’s web components inside a web location.
However, since the identifier is essentially a running counter, if an instance of a web component is embedded on two locations within the embedding application, it’s possible for the states to get "mixed".
Say the user is at location example.com/location-1
, where an instance of embedded-component
is embedded. Now, if the user were to navigate to example.com/location-2
and that page also had an instance of embedded-component
embedded, the preserved state would be displayed on the embedded-component
in the new location location-2
.
If you want the state of the embedded web component to be shared between pages, you don’t need to do anything. However, since the identification is a running number, having multiple instances of the same component on different pages might yield unexpected behavior.
To make sure that the state is preserved in the way you want, you can assign an explicit id
attribute to the web component to get consistent behavior.
Controlling the Identity
Assign an id
attribute to the embedded web component to be explicit about its identity. The manually assigned id
is used in place of the generated component identifier, providing a consistent identity for the embedded web component.
<div>
<embedded-component id="uniquely-preserved"></embedded-component>
</div>
The id
can then be used to make sure that either the state is preserved across locations, or it isn’t preserved. If you want to have the component’s state be preserved across locations, assign the same id
to the web component in both locations:
<!-- location-1 -->
<div>
<embedded-component id="cross-preserved"></embedded-component>
</div>
<!-- location-2 -->
<div>
<embedded-component id="cross-preserved"></embedded-component>
</div>
However, if you want to make sure that the state is preserved only within a particular location, assign different id
attributes to the web component instances in different locations:
<!-- location-1 -->
<div>
<embedded-component id="location-1-preserved"></embedded-component>
</div>
<!-- location-2 -->
<div>
<embedded-component id="location-2-preserved"></embedded-component>
</div>
BD0E7359-683E-43C0-97A2-014874030E71