As long as your collection is Serializable, you don't need a custom
DataSqueezer. The problem is that Tapestry isn't saving the
information about the collection itself. This is the problem I was
having with my String[].
Add a hidden field above your @For to save the items info:
<input type="hidden" jwcid="@Hidden" value="ognl:items" /> <!-- I
don't think "ognl:" is necessary in 4.0, but I'm still using 3-->
and getItems() will not return null in the listener.
Todd
On Feb 17, 2006, at 4:52 AM, Inge Solvoll wrote:
Does there exist an example (vlib or similar) of a page that only gets
information from database on render, and that uses a custom
datasqueezer and
no db fetching for the rewind phase? My ideal design is that all known
information in the rewind phase comes from request parameters, that
way many
synchronization issues can be avoided (request not matching content
from
database or other state).
Inge
On 2/16/06, Inge Solvoll <[EMAIL PROTECTED]> wrote:
Yes, items is always null in pageBeginRender. If I remove the else
clause,
it is also null in the form listener. The else clause just
prevents null
values before render.
I actually expect the values to be null in pageBeginRender, but I
expect
the collection to be populated in the end of the rewind, in the form
listener...
Inge
On 2/16/06, Ryan <[EMAIL PROTECTED]> wrote:
It appears your problem is that getItems() will always be null in
pageBeginRender because at that point parameters have not been
bound.
Try removing that else clause.
Ryan
On 2/16/06, Inge Solvoll < [EMAIL PROTECTED]> wrote:
I guess my (first) problem is simpler than this discussion, I'll
try
to
explain:
When I submit my form, I expect my page properties to be updated
during
rewind automatically, without me having to write any java code
to make
that
happen. But so far I haven't understood how this happens. I include
here a
simple code example that I think illustrates my problem quite well.
Why is
my collection always empty when the form listener is reached? If
I run
the
initItems() method on both rewind and render, the values from the
request
parameters are written into the page properties.
My ultimate question is: Do I really have to get the items list
from
the
database during rewind? Isn't there a way to avoid this, making
tapestry
automatically build the items collection from the request
parameters?
As I
wrote in another similar post on the list about DataSqueezer, I've
tried
creating a datasqueezer for this, but the collection is still
showing
up
empty.
My HTML file:
--------------------------------------------------------------------
------
<body jwcid="@Body">
<form jwcid="@Form" listener="listener:formListener">
<span jwcid="@For" source="ognl:items"
value="ognl:currentItem">
<span jwcid="@Insert" value="ognl:currentItem.name"/><br>
<input type="text" jwcid="@TextField" value="ognl:
currentItem.name"/>
<br>
</span>
<input type="button" jwcid="@Submit" value="Submit form now"/>
</form>
</body>
-------------------------------------------------------------
<page-specification class="Test">
<property name="items"/>
<property name="currentItem"/>
</page-specification>
-------------------------------------------------------------
public abstract class Test extends BasePage implements
PageBeginRenderListener {
static Log log = LogFactory.getLog(Test.class);
public abstract Collection getItems();
public abstract void setItems(Collection c);
public void pageBeginRender(PageEvent event) {
if (!getRequestCycle().isRewinding()) {
initItems();
}
else {
if (getItems() == null) {
setItems(new Vector());
}
}
}
public void formListener(IRequestCycle cycle) {
Collection items = getItems();
for (Iterator iter = items.iterator(); iter.hasNext();) {
Item currItem = (Item) iter.next();
log.debug("Current item id: " + currItem.getId() + ",
name: " +
currItem.getName());
}
}
private void initItems() {
Collection items = new Vector();
items.add(new Item(new Long(1), "Item 1"));
items.add(new Item(new Long(2), "Item 2"));
setItems(items);
}
}
On 2/15/06, Ryan <[EMAIL PROTECTED]> wrote:
You may want to look at the method prepareForRender(). This is the
method that handles binding of properties to form values. It is
also
called just before the component is rendered and in the order in
which
they are rendered on the page (where pageBeginRender is called
before
anything renders and is called in an undefined order). Also note
that
prepareForRender is not called if the component is not rendered
(for
instance if it is in an @Conditional that evaluates to false).
I have received the best results from using pageBeginRender for
initializing page properties that are static (ie known at all
times
during render, for instance a property select model property) and
using prepareForRender in other times.
Ryan
On 2/14/06, Inge Solvoll <[EMAIL PROTECTED]> wrote:
I would like to provoke some debate on whether this is a good
design
pattern
or not:
public void pageBeginRender(PageEvent event) {
initState();
readItemsFromDatabase();
}
private Collection readItemsFromDatabase() {
return getDatabaseConnection().getItems();
}
private void initState() {
// Init all crucial page state here
}
My problem is that some ids in hidden inputs are needed by the
initState
method. These values are not available in the pageBeginRender
method
during
rewind, because the Hidden components containing them haven't
been
rendered
yet. I need this state information on a per-request basis, not
per-session,
so it is not possible to persist the page property. So far, I'm
solving
this
by using good-old request parameters, and reading them the old
servlet
way
in the pageBeginRender method like this:
String crucialId = getRequest().getParameter("crucialId");
page.setCrucialId(new Long(crucialId));
I generally run into a lot of problems trying to find a good
pattern for
setting up data to fit with the RequestCycle. I have ended up
doing the
database reading in the pageBeginRender method, meaning that my
data for
the
page is being read on every single rewind and render. I find it a
bit
hard
to understand how to achieve this:
On render:
- Read data from database and set page properties
On rewind:
- Create non-null, empty, page properties ready to be populated
from the
request.
My rewind step here often fails, and I don't see why. My page
properties
don't seem to be populated, when I leave them as, say, a non-null
empty
java.util.Collection to be populated with items from the request.
Long and not very concentrated post, I actually don't know where
to
start
here :)
Inge
--------------------------------------------------------------------
-
To unsubscribe, e-mail: tapestry-user-
[EMAIL PROTECTED]
For additional commands, e-mail:
[EMAIL PROTECTED]
--------------------------------------------------------------------
-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: tapestry-user-
[EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]