0
votes

I have a GWTP Presenter in which I want to add an undetermined number of instances of GWTP PresenterWidget. To each of that instances I need to pass an argument (a different argument to each instance) that the parent Presenterowns.

There are two things that I need to accomplish here:

1. Instantiate an undetermined number of PresenterWidget

  • Reading here, it looks like I just need a Provider.

2. Transfer to each of those PresenterWidget the argument I want.

  • ProxyEvent does not seem an option since the PresenterWidget has no proxy
  • I need to pass the argument before revealing the PresenterWidget
  • Is it possible or is it a good practice to just declare a public method on the PresenterWidget and access it from the parent presenter?

For example:

public class MyWidgetPresenter extends PresenterWidget<MyWidgetPresenter.MyView>  {

...
    private MyArgument argument;
        public void setArgument(MyArgument argument){
        this.argument=argument;
    }

And then the Parent presenter could:

@Inject Provider<MyWidgetPresenter> myWidgetPresenterProvider;
...

[this could be part of a loop]
MyWidgetPresenter myWidgetPresenter = myWidgetPresenterProvider.get();
myWidgetPresenter.setArgument(argument);
getView().addToSlot(SLOT_MyWidgetPresenters, myWidgetPresenter);
[loop end]

Is this a valid solution at all? I have implemented it and everything works except that my PresenterWidget never calls onReveal or onReset which prevents to show the content. Any ideas why?

2

2 Answers

1
votes

There are different ways to solve this problem, one of them is the way you showed in your own answer.

  1. create a setter on your PresenterWidget and set it from your parent Presenter (how you have done it).
  2. Fire an Event on the EventBus and handle it in your PresenterWidgets (The event contains the EntryProxy instance).
  3. Let the PresenterWidget itself retrieve the data from the backend.

Solution 3 won't work in your case because you have not a single PresenterWidget but as many as you have data.

Solution 2 has the least coupling. However when you use PresenterWidgets you have anyways a coupling between your parent Presenter and your PresenterWidget so there is not much benefit. I would only use this method if you want to use your retrieved EntityProxy elswhere (i.e. breadcrumb PresenterWidget).

Solution 1 (the one you suggested) is fine if you only deal with the EntryProxy in those PresenterWidgets.

0
votes

I am answering this since I found where the problem is. Still I don't know if what I am doing is considered a good practice. [See Ümit's answer]

The reason why my WidgetPresenter was not calling onReveal() or onReset() was because I was calling the view's setInSlot, instead of the Presenter. This can be an easy mistake.

On your presenter never do this:

getView().setInSlot(whatever,whatever)

But rather

[this.] setInSlot(whatever,whatever)

Here is my code, for completeness sake:

The parent Presenter:

@Override
    public void onReset(){
        super.onReset();

        /* Request the Topic graph to show using RequestFactory*/
        TopicService service = requestFactory.topicService();
        service.getTopicGraph(movieId).with("entries").fire(new Receiver<TopicProxy>(){

            @Override
            public void onSuccess(TopicProxy response) {
                /* Clear whatever was in the slot before */
                getView().setInSlot(null, null);
                /* Get the Topic and set the title in this Presenter*/
                topic = response;
                getView().setMovieTitle(topic.getName());

                /* Then:
                 * - retrieve the Entries and add them to as many PresenterWidgets as needed
                 * - add those widgets to an slot on this Presenter
                 * - set on the PresenterWidget the Entry, that call also set's the child's view*/
                Iterator<EntryProxy> it = topic.getEntries().iterator();
                while(it.hasNext()){
                    //TODO: pagination
                    ReviewPresenter myRP = myReviewPresenterProvider.get();
                    myRP.setEntry(it.next());
                    setInSlot(SLOT_movie, myRP);
                    reviewPresenterList.add(myRP);
                }
            }

            @Override
            public void onFailure(ServerFailure error){
                getView().setMovieTitle(error.getMessage());
                //TODO use a label or go to error Place
            }

        });;

And the setEntry method on the PresenterWidget:

public void setEntry(EntryProxy entry){
    this.entry = entry;
    getView().setTextArea(entry.getText());
}