The RoutingService (ISIS-666) was implemented in 1.11.0, and I've now also added an FAQ [1] which shows how a custom implementation can use the breadcrumbs to display the previous object in the result of an object being deleted and returning void/null.
This should give the effect that the OP (Yuri) was original after... Thx Dan [1] http://isis.apache.org/guides/ugfun.html#_ugfun_faqs_how-to-handle-void-and-null-results On 23 December 2015 at 14:55, Dan Haywood <[email protected]> wrote: > I've raised ISIS-1282 [1] for this idea. > > Thx > Dan > > [1] https://issues.apache.org/jira/browse/ISIS-1282 > > On 23 December 2015 at 09:01, Óscar Bou - GOVERTIS <[email protected]> > wrote: > >> Hi, Dan. >> >> I like your proposal to extend the @Action annotation. >> >> So, for example, for routing to “this” when returning void or null, would >> it be annotated with something like ”routeUsing=ThisRouter.class”. >> >> Perhaps something clearer would be to have a complementary one like >> “routeTo=THIS” or similar. >> >> Cheers, >> >> Oscar >> >> >> >> >> > El 22 dic 2015, a las 19:13, Dan Haywood <[email protected]> >> escribió: >> > >> > On 22 December 2015 at 15:19, Óscar Bou - GOVERTIS <[email protected]> >> > wrote: >> > >> >> >> >> Hi all. >> >> >> >> I find the SPI Service really useful for advanced use cases. >> >> >> >> But in order to have the desired behavior clearly specified on the same >> >> class definition, shouldn't be helpful to also have an annotation >> >> indicating the desired behavior (like returning this instance)? >> >> >> >> >> > Seems better to provide a lower level SPI service that can work in all >> use >> > cases, and then use that as a building block for higher level >> abstractions >> > that might include annotations (or more likely, a new attribute of the >> > @Action annotation). >> > >> > But to start that conversation, we could have a new "strategy" >> attribute, >> > eg: >> > >> > @Action( >> > routeUsing=MyRouter.class // implements some sort of "Router" >> > interface, similar to our Specification interface >> > ) >> > public void whatever(...) { ... } >> > >> > Cheers >> > Dan >> > >> > >> > >> > >> >> Christmas here also :)) >> >> >> >> HTH, >> >> >> >> Oscar >> >> >> >>> El 22 dic 2015, a las 15:54, Cesar Lugo <[email protected]> >> >> escribió: >> >>> >> >>> Dan, >> >>> >> >>> I think your proposal is quite good to have a configurable "default" >> >> behavior, and having the option to return whatever the developer wants >> is >> >> quite useful as well. Probably this could evolve to some kind of >> wizard (I >> >> saw a work in progress in Isis add-ons), or even some integration with >> some >> >> BPM tool. Just thinking loud here, it's christmas :) . >> >>> >> >>> Cesar. >> >>> >> >>> -----Original Message----- >> >>> From: Dan Haywood [mailto:[email protected]] >> >>> Sent: Tuesday, December 22, 2015 6:02 AM >> >>> To: users >> >>> Subject: Re: How should we handle void and null results >> >>> >> >>> There was a related discussion a while back [1], revolving around >> >> whether the Wicket viewer should always render the returned object, or >> some >> >> other object (eg the owning object/aggregate root). I raised a ticket >> >> ISIS-666 [2] for this, and have also now referenced this thread [3]. >> >>> >> >>> To pick up on a couple of points made: >> >>> >> >>> * should the object returned by the action determine the next object >> >> rendered (ie do domain object actions act as "controllers")? Yu Ri >> says >> >> no, whereas in the previous conversation (Oscar, Jeroen, Dan) I think >> we >> >> were always saying its ok, but to provide the ability for this to be >> >> modified (eg to the aggregate root rather than leaf). We didn't >> discuss >> >> the case of returning void, though. >> >>> >> >>> * Martin was wondering about whether Person#delete() even makes sense. >> >> I think it does though; at least an end-user would want to press a >> button >> >> called "delete" on a domain object. Behind the covers that might be a >> >> contributed action or mixin or double-dispatch back to a repository >> >> service. But that's an implementation detail: the core responsibility >> is >> >> for a domain object to know how to get itself deleted >> >>> >> >>> * Steve suggests that where there is no obvious answer to "which >> object >> >> should be shown next", then the home page might be a reasonable >> default. I >> >> agree, and think we should provide such a capability. >> >>> >> >>> * Cesar illustrates how to return a parent object, eg for both delete >> >> and also for add. >> >>> >> >>> To me it seems that it's unlikely to be a single policy that will >> >> support all use cases. So I propose a new optional SPI service that, >> if >> >> present, the viewer will consult to determine which object to show >> next. I >> >> see this a quite low-level service and we might use it as a building >> block >> >> to some higher-level strategy (eg based on new annotations) at a later >> date. >> >>> >> >>> The SPI I suggest is: >> >>> >> >>> public interface RoutingService { >> >>> >> >>> public Object route(Object original); >> >>> >> >>> } >> >>> >> >>> A default implementation could be something like: >> >>> >> >>> public class RoutingServiceDefault { >> >>> >> >>> public Object route(Object original) { >> >>> return original != null? original: homePage(); >> >>> } >> >>> >> >>> private Object homePage() { ... code to find the @HomePage object if >> >> any ... } } >> >>> >> >>> This behaviour could be overridden eg to support the aggregate object >> >> idea as discussed in [1]. >> >>> >> >>> So, that's my proposal. >> >>> >> >>> Cheers >> >>> Dan >> >>> >> >>> >> >>> >> >>> [1] http://markmail.org/message/xhmeq62ywr2vqvje . >> >>> [2] https://issues.apache.org/jira/browse/ISIS-666 >> >>> >> >>> >> >>>> On 21 December 2015 at 14:46, Cesar Lugo <[email protected]> >> >> wrote: >> >>>> >> >>>> Hello. I am just another Isis user like you, but I thought this might >> >> help: >> >>>> >> >>>> Wicket viewer shows what you "return" in your action method, so, >> >>>> because you are returning void, Wicket is showing "no results" >> >>>> message. Usually, you return the thing you create or update, but you >> >>>> can return the parent if that's what you want, or anything else you >> >>>> need, just get it in your code and return it. For example, I have a >> >>>> method that adds a Deliverer that belongs to a BusinessLocation, and >> >>>> after created shows the parent BusinessLocation entity object instead >> >>>> of showing the Deliverer object just created (in my case, when >> showing >> >>>> the BusinessLocation parent, the Deliverer just created shows in the >> >>>> collection section, which is what I wanted, because Business have >> that >> >>>> collection). If you adapt this code to your deletePerson method I >> think >> >> it can work. >> >>>> >> >>>> My sample code is: >> >>>> >> >>>> @Action( >> >>>> domainEvent = CreateDomainEvent.class >> >>>> ) >> >>>> @MemberOrder(name = "deliverers",sequence = "24") >> >>>> public BusinessLocation addDeliverer( >> >>>> final @ParameterLayout(named="Business Location") >> >>>> BusinessLocation businessLocation, >> >>>> final @ParameterLayout(named="Deliverer Id") String >> >>>> delivererId, >> >>>> final @ParameterLayout(named="First Name") String >> firstName, >> >>>> final @ParameterLayout(named="Middle Name") >> >>>> @Parameter(optionality = Optionality.OPTIONAL)String middleName, >> >>>> final @ParameterLayout(named="Last Name") String lastName, >> >>>> final @ParameterLayout(named="Last Name 2") >> >>>> @Parameter(optionality = Optionality.OPTIONAL)String lastName2, >> >>>> final @ParameterLayout(named="Contact Phone") >> >>>> @Parameter(optionality = Optionality.OPTIONAL)Long contactPhone, >> >>>> final @ParameterLayout(named="Delivery Phone") >> >>>> @Parameter(optionality = Optionality.OPTIONAL)Long deliveryPhone, >> >>>> final @ParameterLayout(named="Deliverer Picture") >> >>>> @Parameter(optionality = Optionality.OPTIONAL) Blob delivererPicture >> >>>> ) >> >>>> { >> >>>> final Deliverer obj = >> >>>> container.newTransientInstance(Deliverer.class); >> >>>> obj.setBusinessLocation(businessLocation); >> >>>> obj.setDelivererId(delivererId); >> >>>> obj.setFirstName(firstName); >> >>>> obj.setMiddleName(middleName); >> >>>> obj.setLastName(lastName); >> >>>> obj.setLastName2(lastName2); >> >>>> obj.setContactPhone(contactPhone); >> >>>> obj.setDeliveryPhone(deliveryPhone); >> >>>> obj.setDelivererPicture(delivererPicture); >> >>>> obj.setCreationTime(clockService.nowAsDateTime()); >> >>>> container.persistIfNotAlready(obj); >> >>>> return obj.getBusinessLocation(); >> >>>> } >> >>>> >> >>>> If you choose to return the parent of the Person object being >> deleted, >> >>>> make sure you get the parent before you Delete the person. Have fun! >> >>>> >> >>>> Cesar. >> >>>> >> >>>> -----Original Message----- >> >>>> From: Y.R Tan [mailto:[email protected]] >> >>>> Sent: Saturday, December 19, 2015 5:44 AM >> >>>> To: users >> >>>> Subject: How should we handle void and null results >> >>>> >> >>>> Hi everyone, >> >>>> >> >>>> When using a void action, let’s say a remove action, the user is >> >>>> redirected to a page "no results". When clicking the back button in >> >>>> the browser the user sees "Object not found" (since you’ve just >> >>>> deleted this object). >> >>>> >> >>>> Example: >> >>>> >> >>>> public class Person { >> >>>> .... >> >>>> public void remove() { >> >>>> ... >> >>>> } >> >>>> } >> >>>> >> >>>> You can return a list for example to prevent the user from being >> >>>> redirect to a "No results" page, but I think it’s not the >> >>>> responsibility of the controllers in the domain model. A solution >> >>>> could be that wicket viewer goes back one page when encountering a >> >>>> deleted object. And refresh the current page when receiving a null >> >> response or invoking a void action. >> >>>> >> >>>> What do you guys think that is the best solution? Or do you have >> >>>> another view on this situation? >> >>>> >> >>>> Looking forward hearing from you. >> >>>> >> >>>> Regards, >> >>>> >> >>>> Yu Ri Tan >> >>>> >> >>>> >> >>>> --- >> >>>> This email has been checked for viruses by Avast antivirus software. >> >>>> https://www.avast.com/antivirus >> >>> >> >>> >> >>> --- >> >>> This email has been checked for viruses by Avast antivirus software. >> >>> https://www.avast.com/antivirus >> >>> >> >> >> >> >
