I’m evaluating/prototyping Vaadin for an application and need a bit of help with something.
I have a “MainLayout” which has a menu bar which contains RouterLinks.
Some of the child pages have a URL Parameter.
My question is, how can I access the URL Parameter from the Main Layout?
I want to update some of the RouterLinks in the MainLayout, based on the URL Parameter received by the child component.
Here is a page that uses MainLayout:
@Route(value = "home", layout = MainLayout.class)
public class HomeView extends VerticalLayout implements HasUrlParameter<String> {
Have you any advice on how to inform the parent layout of the URL parameter(s) ?
Also in the MainLayout I overrode showRouterLayoutContent, so the Parent Layout can add a listener to the child;
class MainLayout extends Div implements RouterLayout {
@Override
public void showRouterLayoutContent(HasElement content) {
RouterLayout.super.showRouterLayoutContent(content);
if (content instanceof ParentNotifier) {
((ParentNotifier) content)
.addParentListener(
ParameterChangeEvent.class,
event -> {
if (!event.getParameterList().equals(this.getParameterList)) {
// Do something with the parameters
}
});
}
}
I also have a ParameterChangeEvent which the ‘child’ can fire from within setParameter
class ParameterChangeEvent extends ComponentEvent<Component> {
private final List<String> parameterList;
public ParameterChangeEvent(Component source, List<String> parameterList) {
super(source, false);
this.parameterList = Collections.unmodifiableList(parameterList);
}
public List<String> getParameterList() {
return parameterList;
}
}
Finally the child has,
class ParameterisedVerticalLayout extends VerticalLayout
implements HasUrlParameter<String>, ParentNotifier {
@Override
public <T extends ComponentEvent<?>> Registration addParentListener(
Class<T> eventType, ComponentEventListener<T> listener) {
Registration registration = addListener(eventType, listener);
// Fire an AppChangeEvent because setParameter is usually called
// BEFORE addParentListener, so we don't want to miss that event.
if (eventType.isAssignableFrom(ParameterChangeEvent.class)) {
// TODO: not sure if fireEvent(...) would be better but that would notify all listeners
listener.onComponentEvent((T) new ParameterChangeEvent(this, this.parameterList));
}
return registration;
}
@Override
public final void setParameter(BeforeEvent event, @WildcardParameter String parameters) {
// Do some things to process the parameters...
fireEvent(new ParameterChangeEvent(this, this.parameterList));
}
It works! But its a lot more code than your solution.
Having the child somehow notify the parent is a valid solution, hopefully you can get it working with the shorter code as well without it requiring too much code in the MainLayout