We are currently in study of transitioning from ADF Faces to Vaadin for our UI layer and are seeking some guidance on a few concepts. Here’s a brief overview of our current setup:
UI Layer (ADF Faces): We use JSPX for defining UI components, with server-side binding managed via UIBean classes. These beans contain the UI components, and we bind them to the JSPX views.
Navigation (Spring WebFlow): We manage navigation using Spring WebFlow, and the lifecycle of our scoped beans and data (conversation scope, flow scope, request scope, etc.) is also handled through Spring WebFlow.
Given this context, we have a few specific questions as we move to Vaadin:
Retrieving Components by ID:
In ADF/JSF, there is a provision to retrieve any child element or node using its ID. Is there a similar mechanism in Vaadin to get any child component by its ID?
Defining Component Hierarchy:
In ADF, we define our component hierarchy in JSPX. How can we define such component hierarchies in Vaadin? Do we need to implement any specific interfaces or override any methods for each view, or is there a more straightforward approach?
View Creation and Spring Beans:
In the Vaadin documentation and many online examples, views are created using the new keyword. In ADF, we often rely on Spring to manage the scope of our views (conversation scope, flow scope, etc.).
Does Vaadin recommend creating views this way, or can we also define views as Spring beans with specific scopes as needed (similar to how we do in ADF)?
We’d appreciate any insights or best practices from those with experience in similar migrations!
This is generally doable. Every Component instance is backed by an Element which is in turn backed by an internal “state node” which has an id. There is one special case with Composite since you then have multiple component instances backed by the same element instance.
Given a node id, the happy path (i.e. without null checks) to the component is like this.
StateNode node = ui.getInternals().getStateTree().getNodeById(nodeId);
Element element = Element.get(node);
Component component = ComponentUtil.getInnermostComponent(element);
You can find the node id of a component instance using component.getElement().getNode().getId().
Defining Component Hierarchy
You create the component hierarchy programmatically, e.g. like this.
VerticalLayout parent = new VerticalLayout();
TextField child = new TextField();
parent.add(child);
There is no built-in template language for defining a server-side component hierarchy. You can use Lit or React to create a client-side template that you then wrap as a single server-side component.
View Creation and Spring Beans
Views annotated with @Route are automatically managed as a bean when you’re using Spring which means that you can inject other beans into the view using the regular Spring mechanisms.
Note that there’s a separate view instance for every browser tab where it’s used which means that the views are treated as prototype scoped beans. You can also inject child components as beans as long as you remember to define it as prototype scoped. In practice, it’s usually simpler to just inject service beans into the top-level view and then instantiate child components with the new keyword and manually pass any needed services to those instances.