Vaadin 7:UI 与 Navigator+Views 的使用

Posted

技术标签:

【中文标题】Vaadin 7:UI 与 Navigator+Views 的使用【英文标题】:Vaadin 7: Usage of UI vs. Navigator+Views 【发布时间】:2013-12-11 11:01:39 【问题描述】:

在 Vaadin 7 中,一个 Web 应用程序可以有多个入口点;用户界面。每个UI 只能有一个包含Views 的Navigator。

我们正在开发一个需要多级导航的应用程序,对于某些屏幕,我们不知道是应该有一个带有导航器的 UI 还是多个带有共享菜单组件的 UI。

UI 和 Navigator 的优缺点是什么?有没有关于这个选择的指导方针?

【问题讨论】:

【参考方案1】:

我建议使用一个带有 Navigator 的 UI,因为我认为这足以完成这项工作。许多 UI 的主要不便之处是在它们之间切换时重新加载。此外,您还需要记住所需的一致性,例如。在每个 UI 中具有相同的标题。根据我的经验,您肯定会遇到更多问题;-)

要使其干净,您应该使用MVP patter。我使用与此类似的 com.google.common.eventbus.EventBus 来处理事件。我将 eventBus 添加到我的视图中,在那里发布事件并在适当的演示者中处理它们,而不是在我认为更成问题的视图中实现侦听器。由于 MVP 已经保留了“演示者”和“视图”,我将 Vaadin 视图称为“页面”。

您可以创建页眉、页脚主菜单,然后创建内容容器(例如一些布局)以连接导航器:

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);

那么就有不同的可能:

在页面的输入方法(Vaadin 视图)中确保显示相应的子菜单。

将其作为参数添加到 ChangePageEvent 并在 changePage 方法中处理。

在 PageEnum 中将其硬编码为新字段,例如。 subMenu 并为子菜单创建其他枚举,在 changePage 方法中处理它。

子菜单可能在您连接 Navigator 的容器之外,因此您可以在那里创建 SubMenuPresenter 和 SubMenuView 来处理子菜单更改。

【讨论】:

【参考方案2】:

你的问题让我在过去的 2013 年汗流浃背。 我研究、分析和测试了 Vaadin 7 UI 和 Navigator 的各个方面。

我查看了大量关于该主题的框架、wiki 和论文;与 Vaadin 7 相关和不相关。

那是前一段时间(2013 年初),我对这个主题并不新鲜;无论如何,这些是我能够复活的一些链接:

Vaadin MVP Lite 代表 Vaadin 6 MVP4Vaadin - Basic Principle Views content switching Vaadin 7 Navigator problem - Vaadin forum Sub-navigation - Vaadin forum

我们的需求有点类似于 Vaadin MVP Lite 的场景;但我们需要在视图的组成上更加抽象和灵活。 我努力使用提供的导航器,但它不容易定制。

Navigator 是一个具体的类。 UI 只能有一个导航器。 在 Navigator 构造函数中,您可以找到这一行:

this.ui.setNavigator(this);

Navigator 非常适合大多数具有简单需求的应用程序,并提供开箱即用的良好功能,但它并不是真正用于扩展或定制的。 要记住的另一个方面是,当使用 Navigator 更改视图时,您会更改屏幕上的所有组件;你不能改变小的。

然后我发现这份指南让我走上了一条有趣的道路: Composing the User Interface, Chapter 7 - MSDN Microsoft

这篇文章真的很好,很有启发性;尽管它与 Delphi 或任何其他基于组件的框架的工作方式有许多共同点,但“区域”概念确实是一种祝福。 其他章节也很有趣(模块化应用程序开发和 MVVP)。

最终我们采用了只有一个 UI 的 Region 概念。 简而言之,它的工作原理如下:

有一个 GUI 组件能够托管其他组件;它可以容纳其他组件的地方就像“洞”。每个洞都被注册,它是一个绑定到字符串名称的区域(简单的 hasmap) 通过区域名称,可以将另一个 Vaadin 组件“放置”到区域中以使其可见。

当 UI 被初始化时,一个区域(整个 UI)被注册为“根”区域。 然后,代表登录表单的组件托管在“根”区域中。 如果成功登录尝试,则在“根”区域中托管另一个组件(删除登录组件);这个组件也是一个主机:它注册了另一个名为“main”的区域,并且也有一个左侧导航菜单。 现在,如果想要显示一个组件(例如欢迎页面),可以检索“主”区域并将组件显示出来。

Vaadin Navigator 实现了书签和后退按钮支持。 我很伤心,因为我们没有开发它,但它不是我们应用程序的要求。 恕我直言,Vaadin 人做了一个艰难但很好的决定,让 Navigator 保持简单;状态管理不容易实现。如果将来有一个更可扩展的 Navigator,那就太好了。 无论如何,我认为当前的 Navigator 可以满足大多数普通需求。

我的回答比预想的要长;我希望我的努力能有所帮助。

【讨论】:

以上是关于Vaadin 7:UI 与 Navigator+Views 的使用的主要内容,如果未能解决你的问题,请参考以下文章

Vaadin 7 在执行后台线程后不刷新 UI(仅当它需要超过 5 分钟时)

在基于 SPRING-BOOT JSP 的 web 应用程序中嵌入 VAADIN UI 的 HTTP 405

为啥在 Vaadin 7 中使用 CustomComponent 进行布局?

在 Vaadin UI 上执行异步操作

向UI发送参数并使用Java / Vaadin更新UI

使用手册的示例代码在 Vaadin Flow 中编写 `UI` 子类