Simple and clear. I like it. :-)) But not sure if on the provided example the viewer would prevent to navigate to the newly created one.
I would expect the "logic" to be the next one: 1. Verify if the action is annotated with @NotNavigate or @Navigate. If so, execute that behavior (as it's explicitly mandated). 2. Verify if the action's returned entity is an @AggregateRoot. If so, navigate to it. 3. Verify if the Entity owning the invoked action is an @AggregateRoot. If so, navigate to it. 4. Simply close the dialog. The Isis meta-model validation should forbid to use @Navigate on actions returning void. El 03/12/2013, a las 14:52, Jeroen van der Wal <[email protected]> escribió: > @NotNagivate is indeed a better term. But if we use @AggregateRoot as > default behavior we also need a directive to excplicity move away from the > aggregate: > > @AggregateRoot > public class Invoice { > ... > public Invoice creditThisInvoice() { > // The @AR annotation prevents the viewer going to this new invoice > ... > return newlyCreatedInvoice; > } > } > > Perhapse introduce @Navigate as well? > > > > On Tue, Dec 3, 2013 at 2:02 PM, GESCONSULTOR - Óscar Bou < > [email protected]> wrote: > >> This is a mixed approach and I would prefer it also. >> >> The viewer annotation @Void (if it's for the viewer, perhaps @NotNavigate >> or something more specific or explicit would be better than the generic >> term "void" ) would have preference on the viewer's behavior. >> >> In absence, the logic could be to search for @AggregateRoot on the >> action's entity. >> >> >> El 03/12/2013, a las 13:49, Jeroen van der Wal <[email protected]> >> escribió: >> >>> I also prefer an annotation and not put boilerplate code in the domain >> for >>> ui purposes. An @AggregateRoot annotation doesn't meet all our >> requirements >>> though: we have cases where child objects are an aggregate in it's own: >>> >>> Lease <- @AggregateRoot >>> + LeaseItem <- aggregate for terms >>> + LeaseTerm >>> >>> Another approach in this case would be to use a viewer directive to >> ignore >>> the result of an action and to return to the calling page. Something >> like: >>> >>> public class LeaseItem { >>> ... >>> @Void >>> public LeaseTerm newTerm(...) {...} >>> ... >>> } >>> >>> This solution would also solve situations where you want to navigate away >>> from an aggregate root. >>> >>> Cheers, >>> >>> Jeroen >>> >>> >>> On Tue, Dec 3, 2013 at 12:48 PM, GESCONSULTOR - Óscar Bou < >>> [email protected]> wrote: >>> >>>> >>>> Hi, Dan. >>>> >>>> I like a lot the idea of explicitly having an annotation for Aggregate >>>> Roots (and, "commercially" speaking, it can be a big call to all those >>>> interested on DDD...). I'm sure we will find more use cases for that >>>> annotation in the near future, as it will force us to consider the >> distinct >>>> semantics of ARs vs "child" Entities in different places. >>>> >>>> Also, I like also a lot the idea to have idioms that can be expressed >>>> through Isis templates .... but a bit unsure about imposing them (it's >>>> clearly not the case on what you're proposing). >>>> >>>> I assume that the "target" to evaluate would always be the entity you >> are >>>> invoking the action from. >>>> If it's not an AR, in theory it should be showed without being able to >>>> modify it (as a Value Object) in order to force the invariants imposed >> by >>>> the AR. >>>> Despite that, in our case, we could have contributed actions (from the >> AR, >>>> or actions from the Entity delegated to the AR) that would allow for >>>> properly modifying it within the context of its AR. And, if no >> invariants >>>> must be preserved on some fields, they simply could be safely edited ... >>>> So, basically, if properly implemented through Isis (with disabled, >> hidden >>>> and actions) a "child" entity can safely be edited preserving all >>>> invariants. >>>> >>>> As a derivation, on action invoked on Domain Services, Isis viewers will >>>> always navigate to the returned entity, despite it's an AR or not (no >>>> reason on DDD to return it from a Service, but no need neither to >>>> explicitly forbid it for those following "bad practices"). >>>> >>>> HTH, >>>> >>>> Oscar >>>> >>>> >>>> >>>> >>>> El 03/12/2013, a las 12:21, Dan Haywood <[email protected]> >>>> escribió: >>>> >>>>> That's an interesting idea, Oscar. >>>>> >>>>> The issue arises from the fact that there are potentially two different >>>>> callers of the Order#createItem method: >>>>> a) the Isis framework itself - in which case, as we all know, the >>>> signature >>>>> of the methdo is used to determine presentation/navigation >>>>> b) other domain objects, ie programmatic interaction. In some cases >> the >>>>> caller might want the aggregate root (Order), at other times the >>>> aggregated >>>>> (OrderItem). >>>>> >>>>> Actually, being strict about (b), under DDD the aggregate root should >>>> never >>>>> return one of its constituent parts. That would argue that even for >>>>> programmatic interactions (b) the method should only return Order, not >>>>> OrderItem. >>>>> >>>>> If we relax that rule, though, then one solution is to split out the >>>> method >>>>> according to its two different callers, and have one method delegate to >>>> the >>>>> other; eg: >>>>> >>>>> public class Order { >>>>> public Order createItem( ... ) { >>>>> doCreateItem(...); >>>>> return this; >>>>> } >>>>> @Programmatic >>>>> pubilc OrderItem doCreateItem( .... ) { >>>>> OrderItem item = ... >>>>> ... >>>>> return item; >>>>> } >>>>> } >>>>> >>>>> I suspect the above pattern/idiom is sufficient in many cases. >>>>> >>>>> But if that seems like too much boilerplate, and we really did want to >>>> have >>>>> a single method (such that Isis renders the Order even though an >>>> OrderItem >>>>> is returned) then I think I'd prefer to simply annotate which of our >>>>> entities are aggregate roots, ie >>>>> >>>>> @AggregateRoot >>>>> public class Order { ... } >>>>> >>>>> Then, the rule would be that if the returned object does not have the >>>>> AggregateRootFacet, then we instead navigate to the target aggregate >>>> root. >>>>> >>>>> Thoughts? >>>>> Dan >>>>> >>>>> >>>>> >>>>> >>>>> On 3 December 2013 10:01, GESCONSULTOR - Óscar Bou >>>>> <[email protected]>wrote: >>>>> >>>>>> >>>>>> Really well-looking, Jeroen. >>>>>> >>>>>> Regarding navigability through actions, I think that perhaps there >> are 2 >>>>>> distinct use cases that should be treated differently as such: >>>>>> >>>>>> 1. The user creates an Aggregate Root (such as an Order). As such, >>>>>> normally want to navigate to the newly created one. >>>>>> 2. The user creates an Entity that is part of an Aggregate (such as an >>>>>> Order Line / Item). In this case, normally the user wants to stay on >> the >>>>>> Order by default. If not, he/she can always navigate by clicking on >> the >>>>>> item collections link to the newly created item. >>>>>> >>>>>> Implementing that desired default behavior by Isis could be easily >> done >>>>>> with an annotation that can be associated with an action, such as >>>>>> @NotNavigate (sure there are better names :-). >>>>>> >>>>>> By default, the Isis framework viewers open the action's returned >> entity >>>>>> (such as when invoking Orders.createOrder(...) ), but that behavior >>>> could >>>>>> be overridden annotating with @NotNavigate the ( >> Order.createItem(...) ) >>>>>> action: >>>>>> >>>>>> public class Order { >>>>>> >>>>>> ... >>>>>> >>>>>> @NotNavigate >>>>>> public OrderItem createItem(...) { >>>>>> ... >>>>>> } >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> Currently, we are forced to choose to return void or return an object, >>>> as >>>>>> that mandates the Isis viewer behavior. With that annotation, the >> value >>>>>> returned does not always imposes the navigation behavior. >>>>>> >>>>>> Perhaps there are better solutions or some pitfalls on this proposal. >>>>>> >>>>>> HTH, >>>>>> >>>>>> Oscar >>>>>> >>>>>> >>>>>> >>>>>> El 02/12/2013, a las 22:57, Jeroen van der Wal <[email protected]> >>>>>> escribió: >>>>>> >>>>>>> Thanks for reminding Dan, screenshot now as link [1] >>>>>>> >>>>>>> [1] >>>>>>> >>>>>> >>>> >> https://dl.dropboxusercontent.com/u/1930710/Attachments/Screen%20Shot%202013-12-02%20at%2010.03.35%20PM.png >>>>>>> >>>>>>> >>>>>>> On Mon, Dec 2, 2013 at 10:23 PM, Dan Haywood >>>>>>> <[email protected]>wrote: >>>>>>> >>>>>>>> Hi Jeroen, >>>>>>>> Screenshots get stripped from the mailing list, so you'll need to >> post >>>>>> it >>>>>>>> somewhere online. How about updating the screenshots on Estatio's >>>>>> README? >>>>>>>> >>>>>>>> By the way, I have a further commit... discovered that default >> values >>>>>> for >>>>>>>> parameters are not honoured second time around (ie bring up an >> action >>>>>>>> prompt, then cancel, then bring it up again). >>>>>>>> >>>>>>>> Cheers >>>>>>>> Dan >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On 2 December 2013 21:17, Jeroen van der Wal <[email protected]> >>>>>> wrote: >>>>>>>> >>>>>>>>> The modal dialog really improves the usability, thanks Dan. I've >>>>>> attached >>>>>>>>> attached a screenshot which tells more then thousand words. >>>>>>>>> >>>>>>>>> I just recently learned that you can use java.lang.Object as the >>>> return >>>>>>>>> type of an action and return whatever domain object or collection >> you >>>>>>>>> programmatically decide. So your action basically is the >> controller. >>>>>>>> Nice! >>>>>>>>> Sounds familiar to what Oscar is doing. >>>>>>>>> >>>>>>>>> Cheers, >>>>>>>>> >>>>>>>>> Jeroen >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Mon, Dec 2, 2013 at 7:37 PM, GESCONSULTOR - Óscar Bou < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Good done. >>>>>>>>>> >>>>>>>>>> We also use modal dialogs on our custom viewer to avoid context >>>>>>>>>> switching. The same dialog redirects to a Domain Object if that's >>>> the >>>>>>>>>> result of the action invocation, or currently shows a Collection >> in >>>> a >>>>>>>> grid >>>>>>>>>> on the same dialog if that's the result of the action. The user >> can >>>>>> then >>>>>>>>>> navigate to any of the objects in the collection. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> El 02/12/2013, a las 17:54, Dan Haywood < >>>> [email protected] >>>>>>> >>>>>>>>>> escribió: >>>>>>>>>> >>>>>>>>>>> Hi folks, >>>>>>>>>>> >>>>>>>>>>> just an fyi that I've committed and pushed ISIS-486 [1], to >> render >>>>>> the >>>>>>>>>>> Wicket viewer's action prompts in modal dialogs. This should >> make >>>>>>>> for >>>>>>>>>> a >>>>>>>>>>> better overall user experience. >>>>>>>>>>> >>>>>>>>>>> To use, you'll need to build from source, as per [2]. >>>>>>>>>>> >>>>>>>>>>> In case there are issues, the old behaviour (action prompts on >>>> their >>>>>>>> own >>>>>>>>>>> page) can be enabled by adding the following property: >>>>>>>>>>> >>>>>>>>>>> isis.viewer.wicket.disableModalDialogs=true >>>>>>>>>>> >>>>>>>>>>> into WEB-INF/viewer_wicket.properties (or isis.properties if you >>>>>>>>>> prefer). >>>>>>>>>>> I'll probably remove this original behaviour before pushing out a >>>>>>>> final >>>>>>>>>>> release, though. >>>>>>>>>>> >>>>>>>>>>> Cheers >>>>>>>>>>> Dan >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> [1] https://issues.apache.org/jira/browse/ISIS-486 >>>>>>>>>>> [2] http://isis.apache.org/contributors/building-isis.html >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>> >>>>>> >>>> >>>> >> >>
