首页 > 解决方案 > 避免在 SplitLayout 中刷新内容

问题描述

我在我的 vaadin 应用程序中有一个 splitlayout,在第一列中,我应该显示通过 addToPrimary 方法添加的不同页面,而在第二列中,我应该有一个包含 IFrame 和视频会议的页面。现在的问题是,当我在第一列中更改路线时,即使第二列也会更新,这会刷新 IFrame。showRouterLayoyutContent 的实现如下:

    @Override
public void showRouterLayoutContent(HasElement content) {

    if (this.accessControl.isAccessGranted(UI.getCurrent(), ((ContentView) content).getName()) && ((ContentView) content).getName().equals("contattaView") ) {
        setLayoutCall((com.vaadin.flow.component.Component) content);
    }
    else if (this.accessControl.isAccessGranted(UI.getCurrent(), ((ContentView) content).getName())) {
        setLayoutContent((com.vaadin.flow.component.Component) content);

    }

}

而 setLayoutCall 和 setLayoutContent 两个方法如下:

private void setLayoutContent(com.vaadin.flow.component.Component content) {

    split.addToPrimary(content);

}
private void setLayoutCall(com.vaadin.flow.component.Component content) {

    split.addToSecondary(content);
    split.setThemeName("visible-split");
}

通过导航更新拆分布局的第一列时,如何避免刷新整个内容?


更新:我还展示了一个我正在测试的非常简单的代码。以下类是主要布局:


private SplitLayout split = new SplitLayout();
    private HorizontalLayout hl = new HorizontalLayout();
    private Div firstDiv = new Div();
    private Div secondDiv = new Div();
    public MainView() {
        Button button = new Button("Click me",
                event -> Notification.show("Clicked!"));
        final VerticalLayout menuBar = new VerticalLayout();
        menuBar.add(new RouterLink("first view", FirstView.class));
        menuBar.add(new RouterLink("second view", SecondView.class));
        menuBar.setAlignItems(Alignment.CENTER);
        add(menuBar);
        //split.addToPrimary(firstDiv);
        //split.addToSecondary(secondDiv);
        //firstDiv.setId("first");
        //secondDiv.setId("second");
        //hl.add(firstDiv,secondDiv);
        add(split);
        //add(hl);
    }

    @Override
    public void showRouterLayoutContent(HasElement element) {

        if(element!=null && element.getClass().getName().contains("FirstView")) {
            split.addToPrimary((Component) element);
            //firstDiv.removeAll();
            //firstDiv.add((Component) element);
            //firstDiv.removeAll();      
            //firstDiv.getElement().appendChild(new Element[]{element.getElement()});

        }
        else if(element!=null && element.getClass().getName().contains("SecondView") ) {
            secondDiv.removeAll();
            secondDiv.add((Component) element);
            split.addToSecondary((Component) element);
            //split.addToSecondary(element.getElement().getComponent().get());
        }


    }

虽然这些是添加到拆分中的两个视图:

    @Route(value="v1",layout=MainView.class)
public class FirstView extends VerticalLayout implements RouterLayout  {

    public FirstView() {
        add(new Label("First View"));
    }
}
@Route(value = "v2",layout=MainView.class)
public class SecondView extends VerticalLayout implements RouterLayout {
public SecondView() {
    IFrame frame = new IFrame();
    frame.setSrc("https://www.youtube.com/watch?v=LoigVtPCYPk&list=RDLoigVtPCYPk&start_radio=1");
    add(frame);
}
}

标签: vaadinvaadin-flow

解决方案


您的评论似乎确实是问题所在。

我建议为主要内容创建一个Div包装器,而不是更改它的内容。

private final Div wrapper;

public MyLayout() {
    wrapper = new Div();
    wrapper.setSizeFull();

    split.addToPrimary(wrapper);
}

private void setLayoutContent(com.vaadin.flow.component.Component content) {
    wrapper.removeAll();
    wrapper.add(content);
}

您可能还希望对辅助节点执行相同的操作。此外,为防止在导航时自动删除任何组件,您也可以覆盖removeRouterLayoutContent(在 Vaadin 14 中可用)

@Override
public void removeRouterLayoutContent(HasElement oldContent) {
    // Do nothing, we remove manually in showRouterLayoutContent
}

编辑

如果您不能覆盖removeRouterLayoutContent,您可以尝试创建自己的HasElement要添加的实例。这有点小技巧,但可能是最简单的解决方案。

public void showRouterLayoutContent(HasElement content) {
    if (content.getClass().getSimpleName().contains("TestView")) {
        // Creating a new instance should stop it from being auto removed 
        content = new TestView();
        firstDiv.add((Component) content);
    }
    ...
}

推荐阅读