1

我正在尝试设计我的第一个超级简单的 GWT 应用程序,该应用程序利用了 GWT 的大多数主要 API 功能。我想我已经完成了大约 70 - 80% 的路,但是在翻阅了 GWT 文档、无数文章并在 SO 上发布了许多其他与 GWT 相关的问题之后,我仍然很难理解最后 20 - 30% 需要完全放置这个应用程序。

我已经调用了这个第一个测试应用程序ClickItToWinIt,我希望它看起来像这样:

在此处输入图像描述

当用户单击“Win”按钮时,win-pic.png左侧的图像框中会弹出一张图片(“”)。当用户点击“Lose”按钮时,lose-pic.png同框会弹出一张图片(“”)。用户可以在按钮之间来回点击,以显示不同的图片。这将是一个单页应用程序,在我的机器上本地托管,并且只需要包含 1 个主页、1 个模块/入口点等。

请注意,对于这样一个简单的应用程序,下面提出的打包/类结构肯定是矫枉过正的ClickItToWinIt。然而,不久之后,我想用 GWT 继续做更大更好的事情,所以在我开始使用更复杂的 UI 处理更大的应用程序之前,了解正确的 GWT 编码对我来说很重要。

此外,以下提议的结构基于 Google 似乎孜孜不倦地鼓励的 3 个 GWT 原则:

  • 表现; 客户端速度
  • 安全
  • 关注点分离(MVP 等)以便于测试

最后一项:通常,在我的 PHP webdev 日子里,我在一些站点中使用“主题/皮肤”的概念,方法是使用不同的 CSS 文件部署站点,该文件只是将不同的样式规则应用于相同的 DOM 元素。因此,我可能有一个“ normal-styles.css”文件使网站看起来“正常”,但也有一个“ facebook-styles.css”文件为网站提供 Facebook 的外观(颜色、字体等)等。我会喜欢在这里完成同样的事情,并提出一个net.bfodder.c2w.client.views.themes包含子类的包AbstractTheme。这些子类将在构建时以某种方式注入/烘焙到视图/演示器中,并为我提供一种使用不同主题或皮肤部署应用程序的方法。ClientBundleCssResource是正确的)GWT似乎在 GWT POJO 中具有对象化 CSS 样式。我的子类会以某种方式与我的所有sAbstractTheme绑定CssResource并定义样式。Widget

所以这是建议的src/main/java结构ClickItToWinIt(我正在使用 Google-Eclipse 插件在 Eclipse 3.7 Indigo 中开发):

ClickItToWinIt/
    src/main/java/
        net.bfodder.c2w
            net.bfodder.c2w.client
                MainModule (implements EntryPoint)
                AppController
                ClientFactory
                net.bfodder.c2w.client.views
                    net.bfodder.c2w.client.views.ui
                        WinButton (extends Composite implements ClickHandler; hasA TextButton)
                        LoseButton (extends Composite implements ClickHandler; hasA TextButton)
                        ImageViewer (extends Composite; hasAn Image)
                    net.bfodder.c2w.client.views.containers
                        MainContainer
                        ButtonContainer
                        ImageContainer
                    net.bfodder.c2w.client.views.displays
                        WinActivity (extends AbstractActivity implements AcceptOneWidget)
                        LoseActivity (extends AbstractActivity implements AcceptOneWidget)
                    net.bfodder.c2w.client.views.themes
                        AbstractTheme
                        NormalTheme
                        FacebookTheme --> I really dont't care about FB, just using as an example of a well-known theme/skin
                net.bfodder.c2w.client.presenters
                    IPresenter
                    ButtonPresenter (extends AbstractActivity implements IPresenter)
                    ImagePresenter (extends AbstractActivity implements IPresenter)
                net.bfodder.c2w.client.history
                    InitialPlace (corresponds to http://localhost/clickittowinit)
                    WinPlace (corresponds to http://localhost/clickittowinit/#winning)
                    LosePlace (corresponds to http://localhost/clickittowinit/#losing)
                net.bfodder.c2w.client.events
                    EventBus impl and GwtEvent impls
            net.bfodder.c2w.server
                Not worried about server-side for now; I think I "get" that much!

AppController适用于不属于任何特定IPresenter子类的任何奇怪的应用程序级业务逻辑。这MainModule是一切开始的地方(DI,开始初步Activity等)。按钮放在里面ButtonContainer,按钮放在ImageViewer里面,ImageContainer两个内部容器都放在里面MainContainer(我假设是在里面创建的MainModule)。至于这些 UI 组件的布局和样式,就像我说的,这取决于注入/配置AbstractTheme在其规则集中定义的任何内容。

我使用这里ClientFactory推荐的方便访问应用程序的 GWT 管道的主要部分。

至于 MVP “东西”,这就是我的想法:

public class WinActivity extends AbstractActivity {
    private final ClientFactory clientFactory;
    private final WinPlace place;

    public WinActivity(ClientFactory clientFactory, WinPlace place) {
        this.clientFactory = clientFactory;
        this.place = place;
    }

    @Override
    public void start(AcceptsOneWidget panel, EventBus eventBus) {
        ImagePresenter presenter = clientFactory.getImagePresenter();

        // Inject the presenter with any stateful data here
        // presenter.setImage(getWinImageUri());

        presenter.go(panel);
    }
}

问题!

就像我在上面所说的,我相信我快到了,我只是很难弥合某些事情上的差距。所以我问:

  1. 如何连接我的AbstractTheme子类以使用CssResourceClientBundle以便我的应用程序被注入/配置正确的主题,并且客户端浏览器下载正确的 CSS 文件(normal-style.cssfacebook-style.css)?
  2. 有人可以正确解释IPresenter(来自经典 MVP)AbstractActivity、“显示区域”(AcceptsOneWidget)和Places 之间的关系吗?这里是否存在 1 对 1 对 1 对 1 的关系,或者 GWT 的意图是让每个AbstractActivity或其他一组比率具有多个显示区域?
  3. 如何连接WinPlaceGWT 的 History API?因此,如果用户单击WinButtonLoseButtonWinButton,如何将其保存在浏览器历史记录中,以便他们可以点击前进/后退浏览器按钮并一遍又一遍地重新创建这种使用模式?
  4. WinButton被点击时,它会在事件总线上放置一个点击事件。我在哪里以及如何将处理程序/侦听器连接到 EventBus,它将知道:(a) 更改 中的图像ImageViewer,以及 (b) 将此状态更改存储在 History API 中?
  5. AppController这篇文章中得到了这个想法,不幸的是,它从未提供任何代码片段来说明它的AppController实际外观。任何人(熟悉AppControllerGWT 模式的人)都可以对它的外观有所了解吗?也许它是一个IPresenter没有特定Activity或视图组件的子类?
  6. 总的来说,我知道这类“ amidoinitrite? ”式的问题在 SO 上是不鼓励的,但我必须问任何在战斗中穿的 GWT 退伍军人:我在这里是不是离基地太远了,或者我或多或少遵循 GWT 最佳实践?有什么建议么?

我不想在这里问这样一个“超级问题”,但我宁愿这样做,也不愿用 6 个中等问题把 SO 弄得一团糟,然后一遍又一遍地重复同样的问题设置。另外,通过一个好的代码示例,可能可以一口气回答所有 6 个问题,所以我在这里抓住了机会。

提前致谢。

4

0 回答 0