by ampatspell
in Code
The same I wrote few days ago. Now with better API:
// One actual "place" in app. This class can handle some events and `invoke` itself // then handle it's place request no matter if it comes from History string token or // place change in app. @Singleton public class ShowPersonPlace implements Place { private final PresenterProvider<PeoplePresenter> people; private final PresenterProvider<ShowPresenter> show; @Inject public ShowPersonPlace(PresenterProviderFactory f, Provider<PeoplePresenter> people, Provider<ShowPresenter> show) { // PresenterProvider allows reuse of already bound presenter. More on this later. this.people = f.create(PeoplePresenter.class, people); this.show = f.create(ShowPresenter.class, show); } public String getPattern() { // matches for example "/person/show/zeeba" history token and // creates that token from {"key"=>"zeeba"} parameters return "/person/show/{key}"; } public boolean isPatternAbsolute() { // Will be useful when parent-child relationships will be implemented in Place. // Place will be able to use <parent pattern> + <this pattern> for matching. return true; } // The "application" side of history. When application fires some event this Place can // handle it and cause History.newItem be called. public void bind(final PlaceBindingContext binding) { binding.addHandler(ListClickEvent.getType(), new ListClickHandler() { public void onListClick(ListClickEvent event) { navigateTo(binding, event.getKey()); } }); binding.addHandler(ShowPersonEvent.getType(), new ShowPersonHandler() { public void onShowPerson(ShowPersonEvent event) { navigateTo(binding, event.getKey()); } }); } private void navigateTo(PlaceBindingContext binding, String key) { // Takes current history state (no matter if its this Place or some other) and // overwrites parameter(s) then invokes it what calls History.newItem under the hood. binding.state().set("key", key).invoke(); } public void unbind() { // binding.addHandler takes care of HandlerRegistration but if there's need to // unbind something else, this can be done here. } // This method is called when History state has changed and requested // token matches given Place. public void invoke(final PlaceInvocationContext invocation) { // if place pattern has parameters in it (/foo/{bar} -- bar is parameter) final String key = invocation.get("key"); // Events with Command on completion (sometimes wraps DeferredCommand to // escape current event execution stack). // fireEvent method is delegate to EventBus. here just to simplify things a little. invocation.fireEvent(new WorkspaceSetContentEvent(people, new Command() { public void execute() { // this "people" will come from somewhere when // parent-child relationships will be implemented invocation.fireEvent(new MenuSetActiveEvent("people")); invocation.fireEvent(new PeopleSetContentEvent(show, new Command() { public void execute() { invocation.fireEvent(new ListSetActiveEvent(key)); invocation.fireEvent(new PersonShowEvent(key)); } })); } })); } }
On my TODO list:
WorkspaceSetContentEvent for example)PlaceBindingContext and PlaceInvocationContext methods directly.