> 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.