在地点更改时更新活动状态的最佳做法是什么?想象一下,您有一个带有视图的活动,该活动显示类别列表和类别中的项目列表。如果选择了不同的类别,则应用程序将转到具有类别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;
}
...
答案 0 :(得分:5)
替代方案是:
在活动中收听PlaceChangeEvent
(然后您可以使用FilteredActivityMapper
和CachingActivityMapper
进行活动的缓存 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
的同一个实例,以便Activity
对ActivityManager
无效。查看if (currentActivity.equals(nextActivity)) {
return;
}
PlaceChangeEvent
对我来说,你有2个选择。正如托马斯所说,第一个是听Activity
Place
中的Activity
。您收到的新ActivityManager
可以根据新的网址添加新参数,您可以“更新/刷新”Activity
。
第二个,我发现更符合活动/地点模式的是修改Activity
,以便在ActivityMapper
时Activity
调用更新(地方)方法由{{1}}给出的回复与当前{{1}}。
我还没有尝试过任何这些解决方案,但我很快就会......我当时可能会更新该帖子。
You can find more information in this article I wrote on my blog on that topic
这是我用来帮助我理解模式的一个小模式,希望它会有所帮助:
答案 2 :(得分:1)
我不会在我的ActiviyMapper中做任何逻辑,除了返回一个活动,通过创建一个新的或给一个前一个(或null)。根据我的说法,映射器不必了解refresh()或活动。
如果是这样,那么'refresh()'的逻辑将通过持有令牌的地方给予活动。该令牌应该包含有关请求状态(新页面,重新加载,ID等)的信息。
在活动中,首先,它要求View,与此活动相关的一个(提示:'ClientFactory'给出的单例是一个好习惯),然后它为该视图创建一个演示者,并将它们绑定在一起。
最后,活动将使用该地点的令牌向演示者提供有关状态的任何信息。然后,它会在页面中添加视图。
默认情况下,通过地点和活动,去同一个地方不做任何事情(没有重新加载)是很好的。但您可以轻松地使用令牌和活动映射器来处理它。
希望您能找到适合您的解决方案。古德勒克。