What is the best practise to update Activity state on Place change? Imagine you have an activity with view that displays list of categories and list of items in the category. If different category is selected then app goes to new place with category ID. I want then to only refresh items and not to create new activity that also re-reads category list.
My current approach is like this:
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;
}
...
Alternatives are:
listen to PlaceChangeEvent
s from within the activity (you can then use a FilteredActivityMapper
and CachingActivityMapper
for the caching of the activity in your ActivityMapper
, so that it's reduced to only create a new activity when asked). †
have some component listen to PlaceChangeEvent
s and translate them to business-oriented events, the activity then listens to those events rather than PlaceChangeEvent
s, otherwise the same as above.
decouple the activity from the "screen", make the "screen" a singleton with a reset()
method and call that method from the activity's start
(possibly passing the category ID as an argument in this case). The "screen" being a singleton could then make sure to load the categories list only once.
in your case, you could also simply put the categories list in a shared cache, so that you don't have to reuse your activity by can create a new one, the categories list will be retrieved once and put in the cache, subsequent activity instances will just use what's in the cache. This is similar to the above, but simpler, and the cache could be used by other parts of the application.
I'd personally rather go with your approach though (with a small exception, see below), as it's the simplest/easiest. Decoupling the activity from the "screen" is also an option; the GWT Team started exploring this approach in the Expenses sample (decoupling the activity responsibility from the presenter responsibility with using MVP) without ever finishing it unfortunately.
Other than that, I don't think any best practice has really emerged for now.
†. I don't like coupling my activities with the places they're used with (I don't quite like the coupling for the goTo
calls either, but haven't yet found a clean and simple alternative), so I'd rather not go with this option; and similarly, I'd not pass the place to the activity constructor and refresh
method like you did, but rather extract the information out of the place and pass it to the activity (e.g. in your case, only give the category ID to the activity, not the ItemListPlace
instance; I would then simply call setCategory
in all cases, and not even pass the category ID to the constructor).