我正在尝试设计我的第一个超级简单的 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
。这些子类将在构建时以某种方式注入/烘焙到视图/演示器中,并为我提供一种使用不同主题或皮肤部署应用程序的方法。ClientBundle
CssResource
是正确的)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);
}
}
问题!
就像我在上面所说的,我相信我快到了,我只是很难弥合某些事情上的差距。所以我问:
- 如何连接我的
AbstractTheme
子类以使用CssResource
,ClientBundle
以便我的应用程序被注入/配置正确的主题,并且客户端浏览器下载正确的 CSS 文件(normal-style.css
或facebook-style.css
)? - 有人可以正确解释
IPresenter
(来自经典 MVP)AbstractActivity
、“显示区域”(AcceptsOneWidget
)和Place
s 之间的关系吗?这里是否存在 1 对 1 对 1 对 1 的关系,或者 GWT 的意图是让每个AbstractActivity
或其他一组比率具有多个显示区域? - 如何连接
WinPlace
GWT 的 History API?因此,如果用户单击WinButton
、LoseButton
、WinButton
,如何将其保存在浏览器历史记录中,以便他们可以点击前进/后退浏览器按钮并一遍又一遍地重新创建这种使用模式? - 当
WinButton
被点击时,它会在事件总线上放置一个点击事件。我在哪里以及如何将处理程序/侦听器连接到 EventBus,它将知道:(a) 更改 中的图像ImageViewer
,以及 (b) 将此状态更改存储在 History API 中? - 我
AppController
从这篇文章中得到了这个想法,不幸的是,它从未提供任何代码片段来说明它的AppController
实际外观。任何人(熟悉AppController
GWT 模式的人)都可以对它的外观有所了解吗?也许它是一个IPresenter
没有特定Activity
或视图组件的子类? - 总的来说,我知道这类“ amidoinitrite? ”式的问题在 SO 上是不鼓励的,但我必须问任何在战斗中穿的 GWT 退伍军人:我在这里是不是离基地太远了,或者我或多或少遵循 GWT 最佳实践?有什么建议么?
我不想在这里问这样一个“超级问题”,但我宁愿这样做,也不愿用 6 个中等问题把 SO 弄得一团糟,然后一遍又一遍地重复同样的问题设置。另外,通过一个好的代码示例,可能可以一口气回答所有 6 个问题,所以我在这里抓住了机会。
提前致谢。