【问题标题】:Why page is loaded two times when I use Navigator and SpringViewProvider?为什么我使用 Navigator 和 SpringViewProvider 时页面加载了两次?
【发布时间】:2017-08-27 08:31:09
【问题描述】:

我想在同一个窗口标签中显示不同的页面。我使用类 Empty 和 Empty1。 Empty 类是一个主页,视图 Empty1 被加载到 Empty 中。

名为 Empty 的类:

@Theme("valo")
@SpringUI(path = "empty")

public class Empty extends UI {

   @Autowired
   private SpringViewProvider viewProvider;

   @Override
   protected void init(VaadinRequest request) {
       System.out.println("init Empty");
       final VerticalLayout root = new VerticalLayout();
       root.setSizeFull();
       setContent(root);

       Navigator navigator = new Navigator(this, this);
       navigator.addProvider(viewProvider);
       navigator.navigateTo(Empty1.VIEW_NAME);
   }
}

和名为 Empty1 的类(视图):

@SpringView(name = Empty1.VIEW_NAME)
public class Empty1 extends VerticalLayout implements View {
   public static final String VIEW_NAME = "empty1";

   @PostConstruct
   void init() {
       addComponent(new Label("This is the default view"));
       System.out.println("init Empty1");
   }

   @Override
   public void enter(ViewChangeListener.ViewChangeEvent event) {
       // the view is constructed in the init() method()
   }
}

当我打开新窗口时,我看到“这是默认视图”这句话,没关系。 但是当我查看 trackstace 时,我注意到句子“init Empty1”显示了两次,为什么?

表示视图 Empty1 的内容被加载了两次。 我希望视图只加载一次。

在 'Empty' 类中,最终效果应该是这样的:

@Theme("valo")
@SpringUI(path = "empty")

public class Empty extends UI {

@Autowired
private SpringViewProvider viewProvider;

@Override
protected void init(VaadinRequest request) {
    System.out.println("init Empty");
    final VerticalLayout root = new VerticalLayout();
    root.setSizeFull();
    setContent(root);

    Navigator navigator = new Navigator(this, this);
    navigator.addProvider(viewProvider);

    int optionAuto = 2;

    switch (optionAuto) {
            case 1:
                getUI().getNavigator().navigateTo(Empty1.VIEW_NAME);
                break;
            case 2:
                getUI().getNavigator().navigateTo(Empty2.VIEW_NAME);
                break;
           }
    }
}

它可以工作,但视图“Empty1”或“Empty2”被调用了两次。如何修改代码以使视图只被调用一次?

【问题讨论】:

    标签: java spring navigation vaadin


    【解决方案1】:

    它发生的原因是因为您在Empty.init() 方法中调用了Navigator.navigateTo()。每个导航操作都会创建新的视图 bean 实例(视图不是单例)。在您调用Navigator.navigateTo() 之后,它稍后会在UI.doInit() 方法中再次调用,这会导致第二个bean 创建。

    如果你想让你的“empty1”视图成为默认视图(如果没有在 url 中指定其他视图,则显示该视图),那么这样的东西应该可以工作:

    if ("".equals(navigator.getState())) {
        getPage().setUriFragment("!" + Empty1.VIEW_NAME, false);
    }
    

    当然您也可以将视图命名为"" 以使其成为默认值。

    【讨论】:

    • 我在“空”类末尾添加了您建议的片段代码。我评论了 navigator.navigateTo(...) 行,但它不起作用。此问题的描述如下: java.lang.IllegalArgumentException: Trying to navigate to an unknown state '' and an error view provider not present path : /empty
    • 我稍微编辑了我的问题,也许现在我更好地解释了我想要做什么。
    • 我已经更新了代码,它现在应该可以工作了(它适用于我的 vaadin 8.0.5)。
    • 我还有其他与 Navigator 相关的问题。导致此警告的原因:WARN c.v.spring.internal.DefaultViewCache - 使用的 Navigator 未扩展 SpringNavigator。查看范围支持可能会受到限制,未来版本的 Vaadin Spring 可能会删除对使用普通 Navigator 的支持。我该如何解决这个问题?这个警告重要吗?
    • @Fisherek15 您应该创建一个新问题,此评论部分不适合讨论此类问题。
    【解决方案2】:

    如果您在类 Empty1 上方添加 @UIScope,那么您可以使用 getNavigator().navigateTo() 而无需每次都创建视图 bean 的新实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-03
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      相关资源
      最近更新 更多