I've implemented a GWT application following the recommendations of this tutorial . I also downloaded the sample code, and I noticed that every Presenter of the demo needed to be injected in the main presenter constructor to be instantiated. The author included this in the source:
public class GreetingPresenter extends WidgetPresenter<GreetingPresenter.Display> {
// FUDGE FACTOR! Although this is not used, having GIN pass the object
// to this class will force its instantiation and therefore will make the
// response presenter listen for events (via bind()). This is not a very good way to
// achieve this, but I wanted to put something together quickly - sorry!
private final GreetingResponsePresenter greetingResponsePresenter;
@Inject
public GreetingPresenter(final Display display, final EventBus eventBus, final DispatchAsync dispatcher, final GreetingResponsePresenter greetingResponsePresenter) {
super(display, eventBus);
this.dispatcher = dispatcher;
this.greetingResponsePresenter = greetingResponsePresenter;
bind();
}
I verified that if any Presenter doesn't get injected in GreetingPresenter, it won't be instantiated. For demonstration purposes this is cool because the whole app only has two Presenters, but in a Real-World application this can be a serious inconvenient.
What's the proper way of accomplish Presenter instantiation?
EDIT: Including GIN related classes for reference:
Presenter module:
public class GreetingClientModule extends AbstractPresenterModule {
@Override
protected void configure() {
bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
bind(PlaceManager.class).in(Singleton.class);
bindPresenter(GreetingPresenter.class, GreetingPresenter.Display.class, GreetingView.class);
bindPresenter(GreetingResponsePresenter.class, GreetingResponsePresenter.Display.class, GreetingResponseView.class);
bind(AppPresenter.class).in(Singleton.class);
bind(CachingDispatchAsync.class);
}
}
Ginjector:
@GinModules({ ClientDispatchModule.class, GreetingClientModule.class })
public interface GreetingGinjector extends Ginjector {
AppPresenter getAppPresenter();
PlaceManager getPlaceManager();
}
You can solve this by using Providers. In my Gin Modules I declare my Presenter/Activity along with it's view like this
// Content Area
bind(ContentActivityMapper.class).in(Singleton.class);
// Intro Page
bind(IntroPageActivity.class);
bind(IntroPageView.class).to(IntroPageViewImpl.class).in(Singleton.class);
Then in the Activity Mapper I use the provider like this
public class ContentActivityMapper implements ActivityMapper {
@Inject Provider<IntroPageActivity> introPageProvider;
public Activity getActivity(Place place) {
if (place instanceof DefaultPlace) {
return introPageProvider.get().withPlace(new IntroPagePlace());
}...
I have the withPlace method set up on the ActivityPresenter to allow for it to be injected without an argument. That code looks like this.
public class IntroPageActivity extends AbstractActivity {
private IntroPageView view;
@Inject
public IntroPageActivity(IntroPageView view) {
super();
this.view = view;
}
public IntroPageActivity withPlace(IntroPagePlace place) {
return this;
}
@Override
public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
containerWidget.setWidget(view.asWidget());
}...
I think you are missing your Ginjector and AbstractGinModule definition where you define the GIN bindings from that sample.
I recommend to download the code from the mentioned tutorial and also check out the GIN getting started wiki .
GreetingGinjector :
@GinModules({ ClientDispatchModule.class, GreetingClientModule.class })
public interface GreetingGinjector extends Ginjector {
AppPresenter getAppPresenter();
PlaceManager getPlaceManager();
}
GreetingClientModule :
public class GreetingClientModule extends AbstractPresenterModule {
@Override
protected void configure() {
bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
bind(PlaceManager.class).in(Singleton.class);
bindPresenter(GreetingPresenter.class, GreetingPresenter.Display.class, GreetingView.class);
bindPresenter(GreetingResponsePresenter.class, GreetingResponsePresenter.Display.class, GreetingResponseView.class);
bind(AppPresenter.class).in(Singleton.class);
bind(CachingDispatchAsync.class);
}
}
Entrypoint :
public class GreetMvp implements EntryPoint {
private final GreetingGinjector injector = GWT.create(GreetingGinjector.class);
public void onModuleLoad() {
final AppPresenter appPresenter = injector.getAppPresenter();
appPresenter.go(RootPanel.get());
injector.getPlaceManager().fireCurrentPlace();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.