> 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 google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to 
google-web-toolkit+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to