Its pretty easy. If you have looked at the source code of
CachingActivityMapper you see that it only calls place.equals(lastPlace) to
check if it has to return the previous activity or has to create a new one.
After construction of CachingActivityMapper both lastPlace and lastActivity
are null and thus the first place.equals(lastPlace) will always return false
and a new Activity for that requested place is created. Lets say the first
place change has been done via placeController.goTo(new EntityPlace(1)) and
now a second place change occur via placeController.goTo(new
EntityPlace(2)).
The CachingActivityMapper will not return a cached activity if you do not
have overwritten .equals() and .hashcode() in the EntityPlace class. If you
do not overwrite both methods, the ones from Object will be used and
.equals() in Object does a instance check (return this == other). But as you
create new instances of EntityPlace the equals call in CachingActivityMapper
will always be false.
So if you overwrite equals/hashcode you would normally check if the class
types are the same and if all variables (= internal state) are the same. If
both is true then both places are equal. But even with such an equals method
in EntityPalce the CachingActivityMapper still does not work because now new
EntityPlace(1).equals(new EntityPlace(2)) is still false as they do not have
the same internal state.
Thats why you use a filter. In your Place filter(Place place) method you
would do something like:
Place filter(Place place) {
if(place instanceof EntityPlace) {
return new EntityPlace(null);
}
}
So you "nullify" that state of the place and now the CachingActivityMapper
will always receive an EntityPlace without any state information and thus
equals will return true and thus the cached activity for that place type
will be reused. So thats the basic idea on how to make CachingActivityMapper
work. By the way the PlaceController will of course always have the correct
Place with the correct internal state if you call
placeController.getWhere().
In my case I've done it in a slightly other way. So I have taken my
MainActivityMapper of my application and in its getActivity method I do:
Activity getActivity(Place place) {
if(place != null && this.lastPlace != null && place.getClass() ==
this.lastPlace.getClass()) {
return this.lastActivity;
}
this.lastPlace = place;
if(place instanceof XYZPlace) {
return new XYZActivity(place);
} else if(....) {.....} .....
}
That way I will always get a cached activity if two or more places in a row
have the same type. So basically I integrated the caching into my normal
MainActivityMapper and I do not need an extra Filter and do not need GWT's
CachingActivityMapper.
As every activity is now cached it has to implement PlaceChangeEvent.Handler
to get notified on each place change. That way the activity can update its
state based on the place although the activity is cached. In the way I did
it I wouldn't need to implement .equals/hashcode in my places but I have
done it because placeController will not fire a place change event if two
places are equal (maybe you somehow accidentally called
placeController.goTo(new EntityPlace(1)) twice in a row).
But keep in mind that I do it that way because I have only one
ActivityMapper and one Activity for each Place. It was the easiest solution
for me at the time being because I migrate the app to Activities and my
activities deal with both list selection and loading of the selected object.
But maybe my example shows you that its always a bit application dependent
how to implement things. Once you got the basic idea how you can cache
activities you can make it fit into your application.
-- J.
--
You received this message because you are subscribed to the Google Groups
"Google Web Toolkit" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/google-web-toolkit/-/YFlNzNWgiTMJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-web-toolkit?hl=en.