我在vaadin应用程序中有一个拆分页面,在第一列中,我应该显示通过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);
}
}
答案 0 :(得分:0)
您的评论确实确实是问题所在。
我建议为主要内容创建一个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);
}
...
}