6

在地点更改时更新活动状态的最佳做法是什么?假设您有一个带有视图的活动,该视图显示类别列表和类别中的项目列表。如果选择了不同的类别,则应用程序将使用类别 ID 转到新位置。然后我想只刷新项目而不是创建也重新读取类别列表的新活动。

我目前的做法是这样的:

public class AppActivityMapper implements ActivityMapper {

    private ItemListActivity itemListActivity;

    ...

    public Activity getActivity(final Place place) {
        final Activity activity;

        if (place instanceof ItemListPlace) {
            if (itemListActivity == null) {
                itemListActivity = new ItemListActivity((ItemListPlace) place, clientFactory);
            } else {
                itemListActivity.refresh((ItemListPlace) place);
            }
            activity = itemListActivity;
        } else {
            itemListActivity = null;
        }

        ...
        return activity;
    }

    ...
4

3 回答 3

5

替代方案是:

  • PlaceChangeEvent从活动中收听s (然后您可以使用FilteredActivityMapperandCachingActivityMapper缓存活动中的活动ActivityMapper,以便在被询问时仅创建一个新活动)。†</p>

  • 让一些组件监听PlaceChangeEvents 并将它们转换为面向业务的事件,然后活动会监听这些事件而不是PlaceChangeEvents,否则同上。

  • 将活动与“屏幕”分离,使“屏幕”成为带有reset()方法的单例,并从活动中调用该方法start(在这种情况下可能将类别 ID 作为参数传递)。作为单例的“屏幕”可以确保只加载一次类别列表。

  • 在您的情况下,您也可以简单地将类别列表放在共享缓存中,这样您就不必通过创建新的活动来重用您的活动,类别列表将被检索一次并放入缓存中,后续活动实例只会使用缓存中的内容。这与上面类似,但更简单,并且缓存可以被应用程序的其他部分使用。

我个人宁愿采用你的方法(有一个小例外,见下文),因为它是最简单/最容易的。将活动与“屏幕”分离也是一种选择;GWT 团队开始在 Expenses 示例中探索这种方法(使用 MVP 将活动责任与演示者责任分离),但遗憾的是从未完成。

除此之外,我认为目前还没有真正出现任何最佳实践。


†。我不喜欢将我的活动与它们使用的地方结合起来(我也不太喜欢goTo调用的结合,但还没有找到一个干净简单的替代方案),所以我宁愿不去使用此选项;同样,我不会refresh像您那样将位置传递给活动构造函数和方法,而是从该位置提取信息并将其传递给活动(例如,在您的情况下,仅将类别 ID 提供给活动,不是ItemListPlace实例;然后我会setCategory在所有情况下都简单地调用,甚至不将类别 ID 传递给构造函数)。

于 2012-08-22T13:44:49.410 回答
3

在我看来,

  • the 的作用ActivityMapper是给你一个Activityfrom a Place
  • 的作用是从给定的返回ActivityManager开始,如果不同则停止当前的。在您的情况下,您想“更新/刷新”当前的.ActivityActivityMapperActivity

所以我会修改ActivityMapper它,因为它总是会给我返回Activity给定类型的相同实例Place。这样做的一个好方法是使用 GIN 并使用单例范围...in(Singleton.class)注入您的Activity.

如果您这样做,在更改 url 时,如果地点保持不变(意味着您的 url 在 # 之后和之前 :) 具有相同的单词,因此您的地点的类型保持不变,这ActivityMapper将给您返回相同的实例Activity所以ActivityManager就什么都不做了Activity。检查 l.126 的ActivityManager

if (currentActivity.equals(nextActivity)) {
  return;
}

对我来说,你有两个选择。第一个,正如 Thomas 所说,是PlaceChangeEvent在你的Activity. 您将收到的新Place参数可以根据给定的新 url 在内部包含新参数,并且您可以“更新/刷新”您的Activity.

第二个,我发现更符合 Activity/Place 模式的方法是修改 ,ActivityManager以便它在返回Activity时调用 update(Place) 方法与 current 相同。ActivityActivityMapperActivity

我还没有尝试过这些解决方案中的任何一个,但我很快就会......我可能能够在那个时候更新那个帖子。

您可以在我在我的博客上写的关于该主题的这篇文章中找到更多信息

这是我为帮助我理解模式而制作的一个小模式,希望它会有所帮助:

在此处输入图像描述

于 2013-02-27T10:11:04.350 回答
1

我不会在我的 ActiviyMapper 中执行任何逻辑,除了返回一个活动、创建一个新活动或提供前一个活动(或 null)。据我说,映射器不必知道 refresh() 或活动的作用。

如果是这样,那么“刷新()”的逻辑将通过持有令牌的地方提供给活动。该令牌应该保存有关请求状态(新页面、重新加载、ID 等)的信息。

在活动中,首先,它请求与此活动相关的视图(提示:由“ClientFactory”提供的单例是很好的做法),然后它为该视图创建一个演示者,并将它们绑定在一起。

最后,活动将使用该地点的令牌向演示者提供有关状态的任何信息。然后,它在页面中添加视图。

很高兴知道默认情况下,对于地点和活动,去同一个地方不会做任何事情(不重新加载)。但是您可以使用令牌和活动映射器轻松处理它。

希望您能找到适合您情况的解决方案。祝你好运。

于 2012-08-23T20:25:07.423 回答