[TransWarp] peak.web and forms
Phillip J. Eby
pje at telecommunity.com
Tue Aug 5 14:47:09 EDT 2003
At 08:15 PM 8/5/03 +0200, Roché Compaan wrote:
>* Phillip J. Eby <pje at telecommunity.com> [2003-08-05 16:32]:
> > Now that I've explained all that,
>Thank you very much, I really appreciate it. There are a lot classes in
>the web mix at the moment and to get one's head around - an updated web
>example will really help ground the concepts and make more feedback
It's coming. I'm just trying to get everything finished, first.
> > Of course, I'm not sure that this really saves anything. It may be that I
> > should just work out how to easily invoke a template from inside a method
> > on an object.
>At the moment they can only be invoked from a TraversalContext, right?
Well, it's more correct to say that a DOMlet needs a traversal context in
order to run. renderTo() now takes a context and a state. (Hm, I should
update the interface, which I think still says 'data' is a
traversable. Now it's a context.)
>And a WebTraversable has access to the traversal context so one should
>be able to instruct a template to render itself from there as well?
No, traversables don't have access to a context, they always take it as a
parameter. This is important for traversables to be reusable in different
contexts. Consider a traversable that wraps a "Contact" object... it
can't/shouldn't know if the Contact was accessed by traversing from an
"Order", or by direct access from a specialist.
Before last weekend, traversables did know this, and things were too
complicated and variable. Now, there are three objects involved in any
1. The traversal context, which knows how you got to where you are, what
interaction this is part of, and also holds the next two items...
2. A traversable, which knows how to traverse the..
3. Current domain object being traversed. If the domain object is
traversable, then #2 above is the same object as this.
So, the traversal context holds everything you need to do
anything. context.contextFor('name') returns the context that results from
traversing to 'name'. It does this by asking the traversable (#2 above) to
traverseTo('name',interaction), and then it wraps a new context around the
result, using self.subcontext('name',result).
> > One thing that talking about this scenario has brought up,
> > is that there's currently no way to get at the traversal context from
> > inside a method like this, so that makes things harder.
>Inside methods of which other objects should a template be accessible?
>It sounds convenient to have access to the context all over the place
>but on the other hand if one only has access to the traversal context
>from within a web traversable or a decorator won't this enforce a modular
>design? Anyway, it feels like I might be missing the point again,
>or lacking context ;-)
Well, the problem is equivalent, because it might be that the method we're
talking about is on the traversable, or it might be on the domain object,
or the domain object might be traversable. So that issue isn't really
> > Otherwise, you
> > could just say something like:
> > return context.subcontext('addForm', self.addForm).render()
> > or:
> > return context.contextFor('addForm').render()
>What is the difference between just "context" and
>"contextFor('addForm')" in the line above.
If you're actually asking here about the difference between
'subcontext(name,ob)' and 'contextFor(name)', it's that 'contextFor(name)'
does the work of figuring out for you, what 'ob' should be in the call to
> I know the interface says
>contextFor returns a new traversal context but why would you want one?
Because contexts want to be immutable. That way, if I pass a context
through to a method I call, I don't have to worry about that method
modifying my context. It's a bad idea to divorce allocation from usage in
this fashion. If I always create a new object when I need new data, then
the management burden doesn't propagate all over the code. Think of it as
making the code that wants something, pay the price for getting it.
Another convenient side effect, is that because contexts chain to one
another, they get the caching benefit of their use of bindings. For
example, a given context will compute its absolute or traversed URL at most
once, and any child contexts spun off from it will get the benefit of this
in how long it takes for them to compute their own URLs. E.g.:
If I start with the root traversal object, and do 'contextFor("foo")', and
then take that object and get its 'contextFor("bar")', I will have a
component tree as shown above. Asking for a 'contextFor("..")' will go
back up the tree and reuse the previous traversal context, which also
contributes to caching effects.
More information about the PEAK