Migration
When the Tabbed Application Mode add-on is added, Vaadin’s navigation functionality is disabled. As a result, navigation events like BeforeEnterEvent
and AfterNavigationEvent
are no longer sent to views. Consequently, you may need to refactor views that rely on these events.
To simplify refactoring, the base View
class provides the processBeforeEnterInternal()
method, which accepts a BeforeEnterEvent
as an argument.
Regular Views
For example, consider a view that has a mandatory route parameter used to find the data required for further operations:
@Route(value = "role-assignment/:username", layout = DefaultMainViewParent.class) (1)
@ViewController(id = "RoleAssignmentView")
@ViewDescriptor(path = "role-assignment-view.xml")
public class RoleAssignmentView extends StandardView {
private UserDetails user;
@Override
public void beforeEnter(BeforeEnterEvent event) {
findUser(event.getRouteParameters()); (2)
super.beforeEnter(event);
}
private void findUser(RouteParameters routeParameters) {
String username = routeParameters.get("username")
.orElseThrow(() -> new IllegalStateException("Username not found")); (3)
String decodedUsername = urlParamSerializer.deserialize(String.class, username);
user = userRepository.loadUserByUsername(decodedUsername);
}
}
1 | View route includes a mandatory parameter. |
2 | Obtains route parameters and uses them to find a user instance. |
3 | Gets a particular route parameter and loads a user instance. |
To make this view work within a tab, override the processBeforeEnterInternal()
method and call the findUser
method inside it:
@Override
protected void processBeforeEnterInternal(BeforeEnterEvent event) {
super.processBeforeEnterInternal(event);
findUser(event.getRouteParameters());
}
Detail Views
A detail view provides two methods for initializing the edited entity:
-
setupEntityToEdit(String)
- invoked when a detail view is opened via navigation, and the edited entity is loaded using itsID
, passed as a route parameter. -
setupEntityToEdit(Entity)
- invoked when a detail view is opened in a dialog window, and the edited entity is passed directly.
Consider an example where your detail view has custom code that initializes the edited entity based on the route parameter:
@Override
protected void initExistingEntity(String serializedEntityCode) {
String code = urlParamSerializer.deserialize(String.class, serializedEntityCode);
ResourceRole roleByCode = roleRepository.findRoleByCode(code);
ResourceRoleModel resourceRoleModel = roleModelConverter.createResourceRoleModel(roleByCode);
childRolesDc.mute();
childRolesDc.setItems(loadChildRoleModels(resourceRoleModel));
childRolesDc.unmute();
ResourceRoleModel merged = dataContext.merge(resourceRoleModel);
roleModelDc.setItem(merged);
}
In the example above, the actual edited entity instance is obtained by converting the data stored in the database, which is loaded using the id
passed as a route parameter. Because this view is not intended to be opened in a dialog, it lacks corresponding code for handling a directly passed entity instance. To enable this view to function within a tab, override the setupEntityToEdit()
method and provide an empty implementation:
@Override
protected void setupEntityToEdit(ResourceRoleModel entityToEdit) {
// do nothing
}