Create multiple instances of one view with different data?

I have a view called SpaceView which represents the data of one space. I have multiple spaces with different data. Dependend on the data a different number of tabs exists/are opened therefore I need for each Space an own instance of the SpaceView, it is not enough that the data of the space is changed dependend on the selected space.

Space 1: Link to SpaceView.class with uid 123, which has 3 tabs
Space 2: Link to SpaceView.class with uid 567, which has only one tab
These navigation links are created dynamically.

How can I realize this? Spaceview.class:

@Route(value = “application/module/space/:spaceId”, layout = ApplicationLayout.class)
@PermitAll
public class SpaceView extends VerticalLayout implements BeforeEnterObserver {

private ApplicationService applicationService;
private SharedFolderService sharedFolderService;
private SpaceService spaceService;
private SpaceController spaceController;

private SpaceSingleView spaceSingleView;

public static String url = "application/module/space/";

public SpaceView(ApplicationService applicationService, SharedFolderService sharedFolderService, SpaceService spaceService) {
    this.applicationService = applicationService;
    this.sharedFolderService = sharedFolderService;
    this.spaceService = spaceService;
    this.spaceController = new SpaceController(applicationService.getOrganization());

    this.setSizeFull();
    this.addClassName("no-margin");

    this.spaceSingleView = new SpaceSingleView(applicationService, sharedFolderService, spaceService, spaceController);
    this.add(spaceSingleView);
    this.expand(spaceSingleView);
}


/*
@Override
public void setParameter(BeforeEvent beforeEvent, String parameter) {
    System.out.println("SpaceView: setParameter: "+parameter);
}*/

@Override
public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
    String spaceId = beforeEnterEvent.getRouteParameters().get("spaceId").get();
    System.out.println("SpaceView: beforeEnter: "+spaceId);

    // Try to get the space based on the uid and put it into the hashmaps of tabs
    try {
        Space space = spaceService.openSpace(spaceId);
        if(space == null) {
            DefaultNotification.show(AppIcon.error(), "Space nicht gefunden");
            getUI().ifPresent(ui -> ui.navigate(SpaceOverview.class));
        } else {
            this.spaceController.setSpace(space, applicationService.getOrganizationUser());
            this.spaceSingleView.updateComponent();
        }
    } catch (UserHasNoAccessRightsException e) {
        DefaultNotification.notEnoughRights();
    }
}

}

Thanks Florian?

Have you already tried

@Scope("prototype")

as annotion on top of the class? Prototype generates a new instance per request (if used with Spring), but i never have used it and dont know if it works.

Hello,
thank you for the response. I tried it but that changes nothing.

Thanks,
Florian

Can you elaborate the use case a bit more?

  • What do you mean with “tab” (browser tab? Vaadin Tabs tab?).
  • What does the SpaceSingleView do?
  • And why is it not possible to reuse a SpaceView instance (so why not simple remove all children and instantiate controller and single view again for the new id?)

I assume the “reuse” issue addresses the behavior of Vaadin to reuse an existing view instance, when only the route parameter (spaceId) changes?

Just some notes:

  • Routes are by default prototype
  • Vaadin is optimized to re-use the Route if only a parameter is changed, it’s just a state (“no real navigation took place” / “no cleanup of previously used route because it’s still visible”)
  • If you can’t handle auch cases with your current setup, change the way your view is created. e.g. call removeAll () and afterwards re-create the appropriate layouts in your beforeEnter or afterEnter method
2 Likes

Each space consists per default of two tabs:

  • One tab displays a space specifique dahsboard, the second tab shows the folders and files of this space.
  • When I select a file this file e.g. a word document is opened in a separate tab which is closeable.
  • Multiple files can be opened at the same time.
  • Then there are two aditional tabs which can be opened on request which displays the settings of the space and a list with all changes done to the space.
  • Multiple spaces can be opened at the same time using the app layout to switch between them. When e.g. a certain word document is opened in one space and I switch to another one and than go back, I will come back to the tab with the open word document.

This is the overall use case.
It would be very hard to maintain which tabs are opened in which space, on which position the cursor in the word document is positioned etc.

when using a tabsheet and each space is opened in a separate tab this is not problem and works, but this approach would not fit with the UI logic and tabsheet into tabsheet on multiple levels is also not a good design in my opinion.

Thank you for your help!
Florian