I'm not sure it's that thorough; it's just a copy/paste from my app. :)

The reason that the entities are POJOs is simple; the Lift app is simply a
small internal administrative interface for a much larger Java EE
application. I've toyed with the possibility of porting as much of the main
app as possible to Scala, but there's just no time to do it. Also, I really
love having good refactoring support in the IDE, and it's just not there yet
for scala alone, much less hybrid scala/java projects.

Kris

On Wed, Jan 14, 2009 at 3:05 PM, Charles F. Munat <c...@munat.com> wrote:

>
> Kris,
>
> Thank you much for this very thorough exegesis. I'll study it and will
> try to wrap my tiny brain around it. I really appreciate the effort you
> put into it.
>
> One question... why did you choose to implement the entities as POJOs
> instead of as Scala objects? I've been working with the latter without
> too much difficulty, and I'd like to avoid writing Java as much as
> possible. Is there some advantage to using POJOs?
>
> Chas.
>
> Kris Nuttycombe wrote:
> > Hi, Chas,
> >
> > Sorry it's taken me so long to respond to this - I've been pretty buried
> > for the past week.
> >
> > Here's an example of what I'm doing:
> >
> >
> > trait Binding {
> >     def apply(xhtml : NodeSeq) : NodeSeq = xhtml
> > }
> >
> > trait EntityBinding[+T] extends Binding {
> >     def entity : T
> > }
> >
> > trait SubscriptionEventBinding extends EntityBinding[SubscriptionEvent] {
> >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
> >         val transTemplate = chooseTemplate("event", "transactions",
> xhtml)
> >
> >         bind("event", super.apply(xhtml),
> >              "scheduleDate" -> h(entity.getScheduleDate),
> >              "transactions" ->
> > Group(entity.getTransactions.toSeq.flatMap(_(transTemplate)))
> >         )
> >     }
> > }
> >
> > trait BillingEventBinding extends
> > EntityBinding[SubscriptionBillingEvent] with SubscriptionEventBinding {
> >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
> >         bind("event", super.apply(xhtml),
> >              "detail" -> <span>Charges: ${entity.getCharge}; Discount:
> > ${entity.getDiscount}</span>,
> >              "type" -> h("Billing"))
> >     }
> > }
> >
> > trait CancellationEventBinding extends
> > EntityBinding[SubscriptionCancellationEvent] with
> SubscriptionEventBinding {
> >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
> >         bind("event", super.apply(xhtml),
> >              "detail" -> <div>Reason: {entity.getReason}<br/>Final
> > Balance: {entity.getFinalBalance}</div>,
> >              "type" -> h("Cancellation"))
> >     }
> > }
> >
> > Then, in the appropriate scope, I import the correct implicit:
> >
> >     implicit def entityToEventBinding(e : SubscriptionEvent) : Binding =
> {
> >         e match {
> >             case b : SubscriptionBillingEvent      => new
> > BillingEventBinding        { override val entity = b }
> >             case c : SubscriptionCancellationEvent => new
> > CancellationEventBinding   { override val entity = c }
> >             case _ => throw new IllegalStateException("Unbindable event
> > " + e.getClass + " (" + e + ")")
> >         }
> >     }
> >
> > All of the entity classes are JPA entities implemented in Java. If I
> > have a different set of bindings for a different context, I simply
> > create a separate trait. The nice thing about this approach is that the
> > traits are stackable over an inheritance hierarchy, as above.
> >
> > With this in place, I can just treat my entity as a binding context on
> > its own:
> >
> >   object Subscriptions {
> >     object current extends SessionVar[Box[Subscription]](Empty)
> >   }
> >
> > ... stuff that populates the SessionVar
> >
> >   def events(xhtml : NodeSeq) : NodeSeq = {
> >
> >
> Subscriptions.current.is.map(_.events.toSeq.flatMap(_(xhtml))).openOr(h("No
> > subscription to display events for."))
> >   }
> >
> >
> > Kris
> >
> >
> > On Fri, Jan 9, 2009 at 5:29 PM, Charles F. Munat <c...@munat.com
> > <mailto:c...@munat.com>> wrote:
> >
> >
> >     That sounds kinda smart. Is there any chance you could post some
> example
> >     code?
> >
> >     Chas.
> >
> >     Kris Nuttycombe wrote:
> >      > Oh, I'm not complaining about the way User is handled - my
> >     response was
> >      > more about the general hate towards MVC upthread. Having a
> sensible
> >      > default for a standard use case is great, even when I'll probably
> >     never
> >      > use the default.
> >      >
> >      > In my Lift app, my shortcut to different renderings (well,
> different
> >      > bindings, really) is to keep all the binding logic for a specific
> >     case
> >      > in a trait and have an implicit conversion from my model to the
> >      > appropriate trait in the relevant scope. You still have to do the
> >     work,
> >      > but it makes the bindings a lot easier to reuse.
> >      >
> >      > Kris
> >      >
> >      > On Fri, Jan 9, 2009 at 4:46 PM, Charles F. Munat <c...@munat.com
> >     <mailto:c...@munat.com>
> >      > <mailto:c...@munat.com <mailto:c...@munat.com>>> wrote:
> >      >
> >      >
> >      >     I don't see how you're any worse off if the model can render
> >     itself in
> >      >     one way. And if that way is a common standards-compliant way,
> >     such as
> >      >     rendering to XML, and you include semantic information, then
> >     you can
> >      >     layer any other layers you want on top to do the mapping to
> >     the 30
> >      >     different contexts.
> >      >
> >      >     Saying that an object should know how to render itself to some
> >      >     universally recognized format is not the same as saying that
> >     that solves
> >      >     all rendering issues.
> >      >
> >      >     Is there some shortcut to 30 different renderings that I'm
> >     missing, or
> >      >     do you have to do the work either way?
> >      >
> >      >     Chas.
> >      >
> >      >     Kris Nuttycombe wrote:
> >      >      > If you want to render a model 30 different ways in 30
> >     different
> >      >      > contexts, it kind of sucks though, doesn't it?
> >      >      >
> >      >      > Or what if, shock horror, you don't know how the eventual
> >     system is
> >      >      > going to want to render the model (i.e., the person doing
> the
> >      >     rendering
> >      >      > won't be able to change the model code.) Not too uncommon,
> I
> >      >     don't think...
> >      >      >
> >      >      > Kris
> >      >      >
> >      >      > On Sun, Jan 4, 2009 at 9:58 AM, Michael <mike.sr
> >     <http://mike.sr> <http://mike.sr>
> >      >      > <http://mike.sr>@gmail.com <http://gmail.com>
> >     <http://gmail.com> <http://gmail.com>>
> >      >     wrote:
> >      >      >
> >      >      >
> >      >      >      > Also I was looking at the sample model source code
> >     (User,
> >      >     ProtoUser)
> >      >      >      > and saw presentation logic mixed in it. Shouldn't
> the
> >      >     business and
> >      >      >      > model logic be kept separated from the presentation
> >     logic
> >      >     or is there
> >      >      >      > a Lift strategy it?
> >      >      >
> >      >      >     Hmm, a model that can render itself ... That sounds
> >     like this
> >      >     crazy
> >      >      >     paradigm called object-oriented programming. Some
> radicals
> >      >     say it has
> >      >      >     some advantages over the more procedural style of MVC.
> >      >      >
> >      >      >     -- Michael
> >      >      >
> >      >      >
> >      >      >
> >      >      >
> >      >      > >
> >      >
> >      >
> >      >
> >      >
> >      > >
> >
> >
> >
> >
> > >
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to