GWT MVP更新地方变更的活动状态

时间:2012-08-22 12:26:43

标签: gwt mvp gwt-mvp gwt-places gwt-activities

在地点更改时更新活动状态的最佳做法是什么?想象一下,您有一个带有视图的活动,该活动显示类别列表和类别中的项目列表。如果选择了不同的类别,则应用程序将转到具有类别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;
    }

    ...

3 个答案:

答案 0 :(得分:5)

替代方案是:

  • 在活动中收听PlaceChangeEvent(然后您可以使用FilteredActivityMapperCachingActivityMapper进行活动的缓存 ActivityMapper,以便它被缩减为仅在被询问时创建新活动)。 †

  • 让某些组件听取PlaceChangeEvent并将翻译它们转换为面向业务的事件,然后该活动会监听这些事件而不是PlaceChangeEvent s,否则与上述相同。

  • 将活动与“屏幕”分离,使“屏幕”成为具有reset()方法的单例,并从活动的start调用该方法(可能将类别ID作为在这种情况下的论点)。然后,作为单身人士的“屏幕”可以确保只加载一次类别列表。

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

我个人宁愿选择你的方法(有一个小例外,见下文),因为它是最简单/最简单的。将活动与“屏幕”分离也是一种选择; GWT团队开始在费用样本中探索这种方法(将活动责任与主持人责任与使用MVP分离),而不幸地完成它。

除此之外,我认为现在还没有出现任何最佳实践


†。我不喜欢将我的活动与他们使用的地方联系起来(我不太喜欢goTo调用的耦合,但还没有找到一个干净简单的替代方案),所以我我宁愿不选择这个选项;同样地,我不会像你那样将地点传递给活动构造函数和refresh方法,而是将信息提取出来并将其传递给活动(例如,在您的情况下,只给出类别活动的ID,而不是ItemListPlace实例;我会在所有情况下简单地调用setCategory,甚至不将类别ID传递给构造函数。)

答案 1 :(得分:3)

在我看来,

  • ActivityMapper的作用是从Activity返回Place
  • ActivityManager的作用是启动从Activity返回的ActivityMapper,如果不同则停止当前的Activity。在您的情况下,您希望“更新/刷新”当前的ActivityMapper

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

如果您这样做,在更改网址时,如果地方保持不变(意味着您的网址在#之后和之前的网址相同),那么您的地方类型保持不变,Activity会返回ActivityManager的同一个实例,以便ActivityActivityManager无效。查看if (currentActivity.equals(nextActivity)) { return; }

的l.126
PlaceChangeEvent

对我来说,你有2个选择。正如托马斯所说,第一个是听Activity Place中的Activity。您收到的新ActivityManager可以根据新的网址添加新参数,您可以“更新/刷新”Activity

第二个,我发现更符合活动/地点模式的是修改Activity,以便在ActivityMapperActivity调用更新(地方)方法由{{1}}给出的回复与当前{{1}}。

相同

我还没有尝试过任何这些解决方案,但我很快就会......我当时可能会更新该帖子。

You can find more information in this article I wrote on my blog on that topic

这是我用来帮助我理解模式的一个小模式,希望它会有所帮助:

enter image description here

答案 2 :(得分:1)

我不会在我的ActiviyMapper中做任何逻辑,除了返回一个活动,通过创建一个新的或给一个前一个(或null)。根据我的说法,映射器不必了解refresh()或活动。

如果是这样,那么'refresh()'的逻辑将通过持有令牌的地方给予活动。该令牌应该包含有关请求状态(新页面,重新加载,ID等)的信息。

在活动中,首先,它要求View,与此活动相关的一个(提示:'ClientFactory'给出的单例是一个好习惯),然后它为该视图创建一个演示者,并将它们绑定在一起。

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

默认情况下,通过地点和活动,去同一个地方不做任何事情(没有重新加载)是很好的。但您可以轻松地使用令牌和活动映射器来处理它。

希望您能找到适合您的解决方案。古德勒克。