1

我有一个使用活动和地点的 GWT MVP 应用程序。这是受到 Mauro Bertapelle 的样本(在这个线程中)的启发,显然是基于Thomas Broyer的一些工作。

这就是问题所在:我让 LoginActivity 进行了一个 RPC 调用,如果成功登录,它会返回一个用户。该用户有一个角色(例如,管理员、普通用户、访客)。包括 NavigatorView 在内的多个视图和活动依赖于这个角色来显示或执行。如何将此用户实例获取到其他活动?

我没有 ClientFactory;注入(Gin)用于实例化提供我的活动/演示者的 ActivityProviders 中的视图,并将 ActivityProviders 注入到我的 ActivityMapper 中。所以这可能会简化为一个杜松子酒问题:我如何在需要的地方获得用户参考?这似乎类似于关于 MVP 中全局引用的SO question 。

考虑我是杜松子酒新手,这是我第一次尝试使用它。我猜有一种“杜松子酒方式”可以实现这一点,但我对杜松子酒的了解还不够,无法知道最好的方法(如果应该使用杜松子酒的话)。

非常感谢。

编辑 1:尽管我尽最大努力搜索类似的问题,但我发现这个问题与我的几乎相同(用于查找“相关”链接的 SO 算法是否比搜索更好?)。我认为大卫的杜松子酒回答是正确的。

我认为 EventBus 解决方案是不可能的。我遵循Google 指南,其中涉及在每次 Place 更改时实例化 Activity,因此单个 Event 本身是不够的。

4

2 回答 2

3

我在服务器端与 Guice 一起使用并且在客户端也能正常工作的东西是绑定到自定义提供程序。但是,在您的情况下,您必须使提供者成为单例并从您的 RPC 回调中将值推送到其中(而不是从某些上下文中提取它)。您首先需要一个特定的提供者:

@Singleton
public class CurrentUserProvider implements Provider<User> {
  private User currentUser;

  public User get() { return currentUser; }
  public void setCurrentValue(User currentUser) {
    this.currentUser = currentUser;
  }
}

您将绑定User到提供程序:bind(User.class).toProvider(CurrentUserProvider.class) 在您的 RPC 回调中,您将注入 aCurrentUserProvider以便您可以setCurrentValue,但在其他任何地方您将注入Provider<User>以保留CurrentUserProvider作为实现细节。对于非常短暂的对象,您可以直接注入一个User值而不是一个Provider<User>.

如果您需要通知对象值的变化,您可以在全局事件总线上调度一个事件。

或者,您可以始终使用具体CurrentUserProvider类型(不再需要实现Provider)并可能将其设置为 aHasValueChangeHandlers以便您可以在其上而不是在事件总线上注册侦听器(但您必须自己清理您的活动”onStoponCancel避免内存泄漏,而如果您在事件总线上注册处理程序,则会自动处理onStart)。

(如果你问我,我宁愿尽可能在应用程序内进行身份验证)

于 2011-04-30T11:09:20.903 回答
1

我对最近的一个项目有类似的要求。

当我从登录(或注销)RPC 收到回复时,我会在 EventBus 上发送一个自定义 AuthenticationEvent。对此事件感兴趣的所有活动都会监听此事件。AuthenticationEvent 具有对 AppUser 对象的引用,如果用户刚刚注销,则该对象为 null。AppUser 包含所有必要的数据(权限、组等),以便活动可以检查它并对其采取行动。

关于全局引用:您可以拥有一个带有静态方法的类,提供您需要的数据。此类在内部保存对所需实例的单例引用。在我的示例中,我有静态方法 AppUtils.getCurrentUser()。在内部,它包含对 AppUser 的引用,并且还侦听 AuthenticationEvent 以设置/重置此字段。

附带说明:不要依赖客户端来强制执行访问限制 - 您应该将 RPC servlet 分为两组:公共和私有。任何人都可以访问公共(这基本上是登录/注销 RPC 和其他一些公共信息 RPC),而私有 RPC 需要对用户进行身份验证。可以按路径/servlet 设置访问限制:http ://code.google.com/appengine/docs/java/config/webxml.html#Security_and_Authentication

更新:

  1. 正如您所指出的,在此设置中不建议使用具有静态方法的类,因为它不可替换并且这会妨碍测试(这是使用 GIN 的全部要点)。

  2. 解决方案是将保存全局变量 (AppUtils) 的实用程序类注入到需要全局变量的活动中。AppUtils 应该在 GIN 配置中声明为单例,因为一个实例足以满足整个应用程序的需求。

  3. Provider如果要延迟依赖项的初始化(AppUtil 是依赖项),是否使用只是一个问题。由于 AppUtils 是整个应用程序的单例,因此延迟初始化它是没有意义的。

  4. 有时您会遇到屏幕上显示多个活动的情况(在我的情况下是菜单栏和信息栏)。在这种情况下,当用户登录时,您将需要一种方法来通知他们更改。使用事件总线。

于 2011-04-29T20:52:17.813 回答