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
> >>>
> >>
>
>

Reply via email to