> If you don't mind me asking,
>
> - Do you link Activities directly to specific places: Activity<P extends
> Place> ?
> - Somewhat related, do you set an actual "place" (constructor/setter) or
> just a particular param (DTO/other object/variable)?
>
Yes I do. Its like
interface CustomActivity extends Activity<P extends Place> {
void setPlace(P place);
}
Along with an abstract CustomActivityBase class that implements this
interface and adds some protected "isActive" logic: the activity is
considered inactive if cancel/stop is called so that any RPC call and its
onSuccess() code will be disabled in the activities start() method (user
navigates away before RPC returns):
onSuccess(..) {
if(isActive()) {
...//proceed
}
}
> - Do you have a lot of "ActivityWithPlaceProxy" boiler plate?
>
Its more or less the usual if-construct to instantiate the correct activity
for a given place in the ActivityMapper. There is a bit additional code
because of the complete mappers I code split (see below).
> - Do you show any loading on the ActivityWithPlaceProxy.start() prior to
> the actual start of the desired activity?
>
Not yet. Depending on how you want to notify your users you could:
1.) Implement a custom AcceptsOneWidget/SimplePanel/SimpleLayoutPanel that
shows a loading text/icon in the display area when no child widget is set
(on construction and on setWidget(null)).
2.) Fire a custom event on the event bus and let a global notification
mechanism listen for it.
> - I Assume by proxy complete mappers you mean: build a proxy mapper
> delivered via AsyncProvider which will pull all activities in that mapper
> at once??
>
Its a normal ActivityMapper having Gin Provider<ConcreteActivity> as fields
and the usual dispatch code in getActivity(Place). You then have a slightly
different implementation of your AsyncActivityWithPlaceProxy that does not
use an AsyncProvider<CustomActivity> but an AsyncProvider<ActivityMapper>
and loads the mapper in the proxy's start() method. When the mapper is
loaded you get the correct Activity from the mapper using the place that
has been set to the proxy through the ActivityMapper that is assigned to
the ActivityManager and finally start the activity.
Obviously the ActivityMapper assigned to the ActivityManager has to catch
all possible places for that async mapper hidden in the activity proxy:
getActivity(Place place) {
if(place instanceof ConcretePlace1 || place instanceof ConcretePlace2 ||
...) {
AsyncActivityWithPlaceAndMapperProxy activity = //...
activity.setPlace(place) // the internal mapper will dispatch the
place to the correct activity.
}
}
You could mitigate that by introducing a common super class (or marker
interface) for places that are handled by the same async ActivityMapper.
> - It would appear there is a situation when using activities provided via
> RunAsync that the default ActivityMapper behavior is not desired:
> --- In non-RunAsync, if a new Activity starts AND sets the display
> widget/panel prior to the activity which preceded it (user navigates before
> current activity can set display), clear/kill current activity and proceed
> with next
> ---- However, this is not the same when RunAsync is involved as Activity
> "A" can be called and downloaded. Prior to "A" being downloaded, Activity
> "B" is started and downloads or loads faster than "A"
> ---- So "A" will set the display panel AFTER Activity "B" -> The default
> ActivityManager will give control to "A" and kill of "B" even though we
> probably want to give "B" the control and display since "A" took longer
> loading and setting the display...
> ---- I am not sure if my logic fits reality, but I have extended Saeed's
> asyncMapper/Manager example to use the Place to determine what activity
> gets control
> ---- (That last place fired gets control. So if an activity loads but is
> linked - pass the Place as params through the async calls - to a different
> place, kill it)
>
The activity that is active is your AsyncActivityProxy. The start() method
(maybe) does an async RPC call like most ordinary Activities probably also
do to load some data. So your AsyncActivityProxy should also have the same
"isActive" logic like an ordinary activity. So in onSuccess() of
GWT.runAsync() you do:
if(isActive()) { //false if cancel/stop has been called on the proxy while
activity is downloaded
activity.setPlace(place);
activity.start(panel, eventbus);
}
Only the activity that is currently active in the ActivityManager will win
because the previous one will not proceed if the download completes to late
(isActive() is false). Am I missing something?
Speaking in menu items I use the async ActivityMapper to generate a single
split point that contains all the sub menu items of a single main menu
item. As soon as an Activity for a given sub menu item gets too large I
remove it from the async ActivityMapper and code split it separately.
Feel free to ask more :-)
-- 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/-/WnqPKdz4Pv0J.
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.