GWT MVP Update Activity Status on Place Change

What is the best practice for updating activity status when changing location? Imagine that you have activity with a view that displays a list of categories and a list of items in a category. If another category is selected, the application moves to a new location with the category identifier. I want to then update the items, and not create new actions that also re-read the list of categories.

My current approach is 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; } ... 
+6
source share
3 answers

Alternatives:

  • listen to PlaceChangeEvent from inside the action (then you can use FilteredActivityMapper and CachingActivityMapper to cache the activity in ActivityMapper so that it CachingActivityMapper down to just creating a new action when asked). †

  • some components listen to PlaceChangeEvent and translate them into business-oriented events, then the activity then listens to these events, not PlaceChangeEvent s, otherwise the same as above.

  • cancel the action from the “screen”, make the “screen” single with the reset() method and call this method from the start action (possibly passing the category identifier as an argument in this case). A "screen", which is a singleton, could then load a list of categories only once.

  • in your case, you can also just put the list of categories in the shared cache, so you don’t need to reuse your activity to create a new one, the list of categories will be retrieved once and put in the cache, subsequent instances of the activity will just use what is in the cache . This is similar to the above, but simpler, and the cache can be used by other parts of the application.

I would rather go with your approach, though (with a few exceptions, see below), as this is the easiest / easiest. Separating activity from the "screen" is also an option; the GWT team began to study this approach in the “Costs” model (separating the responsibility for the activity from the responsibility of the facilitator using MVP), without ending it, unfortunately.

In addition, I do not think that any good practices have really emerged at the moment.


†. I don’t like associating my activities with the places where they are used (I don’t really like the connection for goTo calls, but I haven’t found a simple and simple alternative yet), so I would rather not go to this option; and in the same way, I would not pass the place to the activity constructor and the refresh method, as you would, but rather extract the information from the place and pass it to the action (for example, in your case specify only the category identifier and not the ItemListPlace instance, I would then just call setCategory in all cases and did not even miss the category identifier to the constructor).

+5
source

To my mind,

  • The role of an ActivityMapper is to return an Activity from Place to you.
  • The role of the ActivityManager is to start the Activity returned from the ActivityMapper and stop the current one if it is different. In your case, you want to “update / update” the current Activity .

Therefore, I would modify the ActivityMapper so that it always returns the same instance of Activity for the given Place type. A good way to do this could be to use the GIN and use the Singleton scope ...in(Singleton.class) to enter your Activity .

If you do this, if you change the URL, if the place remains the same (which means that your URL has the same word after # and earlier :), so that the Type of your place remains the same, ActivityMapper will give you return the same an instance of an Activity so that the ActivityManager does nothing on the Activity . Check l.126 from ActivityManager

 if (currentActivity.equals(nextActivity)) { return; } 

You have 2 options for me. The first, as Thomas said, is to listen to PlaceChangeEvent in your Activity . The new Place that you receive may have new parameters internally based on the new url, and you can "refresh / refresh" your Activity .

The second, which more closely matches the Activity / Place pattern, is to change the ActivityManager so that it invokes the Place method in the Activity when the Activity returned by the ActivityMapper the same as the current Activity .

I have not tried any of these solutions yet, but soon ... Perhaps I can update this post at that time.

You can find additional information in this article that I wrote on my blog on this topic.

Here is a small outline I made to help me figure out the template, hope this helps:

enter image description here

+3
source

I would not do any logic in my ActiviyMapper, except to return the action, creating a new one or providing the previous one (or zero). For me, the cartographer should not know about the update () or what they are doing.

If this is the case, the "refresh ()" logic will be passed to the activity through the place where the token is stored. This token should contain information about what is the status of the request (new page, reload, identifier, etc.).

In this operation, the view associated with this action is first requested (hint: the singleton specified by "ClientFactory" is good practice), then it creates a presenter for this view and links them together,

Finally, the action will use the token from the spot to provide any status information to the presenter. Then the view on the page is added.

It’s good to know by default, with places and events, going to the same place does nothing (without rebooting). But you can take care of this with a token and activity manipulator.

I hope you find an adapted solution for you. Good luck.

+1
source

Source: https://habr.com/ru/post/923473/


All Articles