Change parent layout

I have 2 view

@Tag("div")
@Route(value="company1", layout=MainLayout.class)
public class CompanyComponent1 extends Component {
}

@Tag("div")
@Route(value="company2", layout=MainLayout.class)
public class CompanyComponent2 extends Component {
}

How I can change some details in MainLayout depending on the child view?
User interface BeforeEnterObserver?

Hi there,

In your MainLayout class, you can override the method showRouterLayoutContent and do different stuff depending on which child is inserted.

For example:

@Override
public void showRouterLayoutContent(HasElement content) {
    super.showRouterLayoutContent(content);
	if (content instanceof CompanyComponent1) {
	    // do something
	}
}

With the same method you can also add different children to different slots in you interface.


Gilberto

I’m trying to replace content within a div, but I’m not able to get showRouterLayoutContent to fire - ever. Also, contributing to be frustration is that I have found that the Upload component is not compatible within the context of a class annotated with @Component, only @Route annotation will get an Upload instance to instantiate without throwing errors making my layouts nigh impossible to swap components with Spring Boot. I’m using Vaadin 15.0.5, Spring Boot 2.2.6, and I have my packages scanned with @SpringBootApplication( scanBasePackages = { “my.packages” }).

@Route
public class AppView extends AppLayout implements BeforeEnterObserver {
	public AppView(){
	    addMenuTab("Export", ExportView.class); // Create RouterLink tab
	}
}

@Route(value = "export", layout = AppView.class)
public class ExportView extends FormLayout implements RouterLayout {

	private Div divContent;
	//@Autowired private MyLayout myLayout; //Unsatisfied dependency expressed through field
	
	public ExportView(){
		divContent = new Div();
	}

	@Override
	public void showRouterLayoutContent(HasElement hasElement) {
		// I would like to replace components in divContent, but this method is never fired.
		divContent.getElement().appendChild(hasElement.getElement());
	}
	
	@PostConstruct
	private void init() {
		contentIndex = 0;
		contents.add(new RouterLink(null, MyLayout.class)); // Forced to annotate MyLayout with @Route
		setContent();
	  }
	
	private void setContent() {
    RouterLink content = contents.get(contentIndex);
    if (currContent == content) {
      return;
    }
	
    this.getUI().ifPresent(ui -> ui.navigate(content.getClass())); // get().UI() is always false
	//UI.getCurrent().navigate(content.getClass()); // // Invocation of init method failed; nested exception is com.vaadin.flow.router.NotFoundException if using @ParentLayout on MyLayout or No route found for given navigation target! if using @Route
    currContent = content;
  } 
}

// @Component // Not compatible with Upload
@Route(value = "export/repository", layout = ExportView.class)
// @ParentLayout(ExportPackageView.class) // Invocation of init method failed; nested exception is com.vaadin.flow.router.NotFoundException
public class MyLayout extends VerticalLayout {
	public MyLayout() {
		add(new Upload()); // Throws NullPointerException, Upload.java line 84 getElement().setAttribute("target", "target" attribute does not exist when annotated with @Component. Only seems to work with @Route :(
	}
}