我建议使用带有导航器的一个UI,因为在我看来它足以完成工作。许多UI的主要缺点是在它们之间切换时需要重新加载。此外,您需要记住所需的一致性,例如,在每个UI中具有相同的标题。根据我的经验,您肯定会遇到更多问题;-)
为了使其更清晰,您应该使用MVP模式。我使用类似于这个模式的com.google.common.eventbus.EventBus来处理事件。我将eventBus添加到我的视图中,在那里发布事件,并在适当的presenter中处理它们,而无需在视图中实现监听器,这在我看来更加麻烦。由于MVP已经保留了“presenter”和“view”,因此我称Vaadin视图为“page”。
您可以创建标题、页脚、主菜单,然后使用内容容器(例如某些布局)与导航器连接:
Navigator n = new Navigator(UI.getCurrent(), layout);
为了管理导航,我创建了PagesEnum,并在切换视图时发布ChangePageEvent,该事件将PageEnum.SOME_PAGE作为参数传递。还可以选择显示项目的ID。因此,在MainPresenter中我有:
@Subscribe
public void changePage(ChangePageEvent event) {
String url = event.getPageName();
if (event.hasId()) {
url += "/" + event.getEntityId();
}
navigator.navigateTo(url);
}
然后有不同的可能性:
在页面的enter方法(Vaadin视图)中确保显示适当的子菜单。
将其作为参数添加到ChangePageEvent中,并在changePage方法中处理。
在PageEnum中硬编码为新字段,例如subMenu,并创建其他用于子菜单的枚举,在changePage方法中处理。
子菜单可能在您将Navigator与之连接的容器之外,所以您可以创建SubMenuPresenter和SubMenuView来处理子菜单更改。
你问题的主题让我在2013年非常焦虑。我研究、分析和测试了Vaadin 7 UI和Navigator的各个方面。
我查看了大量与Vaadin 7相关和不相关的框架、维基和论文。
这是一段时间以前的事情(在2013年年初),我对这个主题不是很熟悉。无论如何,以下是我能够找到的一些链接:
我们的需求与Vaadin MVP Lite的场景有些相似;但我们需要更多有关视图组成的抽象和灵活性。 我努力使用提供的Navigator,但它不容易定制。
Navigator是一个具体的类。UI只能有一个Navigator。 在Navigator的构造函数中,您可以找到这行代码:
this.ui.setNavigator(this);
Navigator通常适用于具有简单需求的大多数应用程序,并提供开箱即用的良好功能,但它并不真正适用于扩展或自定义。 另一个要记住的方面是,使用Navigator更改视图时,您会更改屏幕上的所有组件;您无法更改小部分。
然后我找到了这篇指南,让我走上了一条有趣的道路: 构建用户界面,第7章 - MSDN Microsoft
这篇文章非常好,很有启发性;虽然它与Delphi或任何其他基于组件的框架工作方式有很多共同之处,但“区域”概念确实是一种祝福。 其他章节也非常有趣(模块化应用程序开发和MVVP)。
最终,我们采用了仅有一个UI的Region概念。 简而言之,它的工作方式如下:
当UI被初始化时会发生什么是,一个Region(整个UI)被注册为“根”Region。 然后,在“根”区域中托管代表登录表单的组件。 如果进行了成功的登录尝试,则在“根”区域中托管另一个组件(删除登录组件);此组件也是一个托管者:它注册了另一个称为“主要”区域的Region,并且还有一个左侧导航菜单。 现在,如果想要显示一个组件(例如欢迎页面),可以检索“主”区域并放置要显示的组件。
Vaadin Navigator实现了书签和后退按钮支持。 我很难过,因为我们没有开发它,但这不是我们应用程序的要求。 在我看来,Vaadin的人们做出了艰难但正确的决定:保持Navigator简单;状态管理不易实现。将来拥有更可扩展的Navigator将是很好的事情。 无论如何,我认为当前的Navigator已经满足了大多数普通需求。
我的回答比预期的要长;我希望我的努力能有所帮助。