OK, done.

See [1] SPI service, also [2], a supporting service.

The net effect is that any actions returning void or null will now render
the home page if one is defined.  If this behaviour isn't required, then
implement RoutingService with some other algorithm.

Dan


http://isis.apache.org/guides/rgsvc.html#_rgsvc_spi_RoutingService
http://isis.apache.org/guides/rgsvc.html#_rgsvc_api_HomePageProviderService


On 22 December 2015 at 12:02, Dan Haywood <[email protected]>
wrote:

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

Reply via email to