Hey... I did a little follow-up on this and decided to create an "event-safe
loop" that can restore the state of the loop variable using the page
activation context.  It's not quite perfect, but it's good enough for my
needs right now.  For my application, the resulting code ended up looking
much cleaner than the version that used only the event's context to restore
the state.

It works like this:
1) Replace your <t:loop> component with <t:safeloop>  You should specify the
t:id parameter... you'll need to know it for step 3.
2) Provide an encoder for the loop value. This parameter is optional for
<t:loop> but required for <t:safeloop>.  However, only toClient() needs to
be implemented.
3) Annotate your loop value with @LoopValue("loopid") instead of @Property,
where "loopid" is the t:id specified for the <t:safeloop>.

The <t:safeloop> component stores the state, and @LoopValue creates a
special getter that can restore the state.

Unfortunately, there are some additional requirements that I'd like to
remove:
1) The loop source cannot be initialized by lifecycle methods (e.g.
@BeginRender), since they won't get called.
2) You must include "@Inject ComponentResources res;" in your component in
order for the code generated by @LoopValue to compile.
3) The underlying page must provide simple (one-line) boilerplate
onPassivate and onActivate methods, which can be provided by inheriting from
a superclass.
4) Care must be taken if you want to also use the page activation context
for other purposes.

So far, this is working very well for my application.  I haven't tested its
compatibility with the formEncode feature of the normal Loop component.  If
other people are interested, I'm willing to share the source code... but I
probably won't have time to provide much support.

-Nathan


On Tue, Feb 16, 2010 at 11:08 PM, Nathan Kopp <nathan0...@nathankopp.com>wrote:

> Probably the tip I needed was this:
>
> "When using an EventLink inside a loop, be sure that your event handling
> method does not refer to any loop variable either directly or indirectly.
>  Especially be cautions of referring to parameters that may have been bound
> to any loop variable or a field of a loop variable.  If you avoid referring
> to such parameters in the eventlink's event handler (and pass the
> information to that method using the context instead), Tapestry will not
> attempt to process the parameter binding, and therefore no problem will be
> caused by the null loop variable."
>
> I would have found this most easily if it were located in the primary
> documentation for either EventLink or Loop in the component reference.
>
> Tapestry's stack trace actually did a good job highlighting the offending
> line of code, once I figured out what was happening.
>
> Personally, I think it would be great if there would be a way for the Loop
> component to automatically encode loop state into something like the page
> activation context and then automatically restore that point-in-time state
> when processing the eventlink request.  It would work like a blend of the
> page activation context and the formState functionality already in the Loop
> component.  However, this feature isn't really necessary as long as
> developers use the action context and avoid the "gotcha" that I ran into.
>
> -Nathan
>
>
>
> On Tue, Feb 16, 2010 at 10:45 PM, Kalle Korhonen <
> kalle.o.korho...@gmail.com> wrote:
>
>> Nathan, since you invested considerable amount of time debugging a
>> case that seems to be just a standard event bubbling behavior, do you
>> think that there is anything you'd think the framework or somebody
>> could do to make the logical error in your code more visible? I know
>> Tapestry documentation has often been blamed and while "everything is
>> there", it's scattered - if you knew what you are looking for, you'd
>> find it. But on the other side, I don't know how to make it better and
>> I'm sure you can see now why the old-timers annoyingly enough just
>> kept repeating the same message. So, is this just a case of having to
>> learn the tricks of the trade or is there something we could
>> collectively do to improve things?
>>
>> Kalle
>>
>>
>> On Tue, Feb 16, 2010 at 7:18 PM, Nathan Kopp <nathan0...@nathankopp.com>
>> wrote:
>> > For future reference... this in fact turned out to be a bug in my code.
>> >  Under normal circumstances Tapestry will NOT attempt to perform
>> parameter
>> > bindings when processing the EventLink.  However, I accidentally left a
>> line
>> > of code in my event handling method which referenced one of the
>> parameters
>> > which was bound to the loop variable.  The line of code was purely
>> > unnecessary, but it is what caused Tapestry to process the bindings, and
>> > thus trigger a null pointer exception.  Once I removed that line of
>> code,
>> > Tapestry was able to execute my method without any exceptions.  Many
>> thanks
>> > to those who offered the recommendations that eventually led me to
>> locate my
>> > bug and resolve the problem.
>> >
>> > -Nathan
>> >
>> >
>> >
>> > On Tue, Feb 16, 2010 at 9:32 AM, Nathan Kopp <nathan0...@nathankopp.com
>> >wrote:
>> >
>> >>
>> >>
>> >> On Mon, Feb 15, 2010 at 3:21 PM, Thiago H. de Paula Figueiredo <
>> >> thiag...@gmail.com> wrote:
>> >>
>> >>> On Mon, 15 Feb 2010 03:51:08 -0200, Nathan Kopp <
>> >>> nathan0...@nathankopp.com> wrote:
>> >>>
>> >>>  This looks like a bug in your code, most probably by working in a
>> T4-ish
>> >>>>> way in T5.
>> >>>>>
>> >>>>
>> >>>> Well, it's certainly a "bug" in that I'm trying to do something that
>> T5
>> >>>> doesn't seem to handle out-of-the-box.
>> >>>>
>> >>>
>> >>> I disagree. A bug is something that doesn't work like it should. In
>> this
>> >>> case, it could be the lack of a feature, not a bug. Or just lack of T5
>> >>> experience. :)
>> >>
>> >>
>> >> I have to laugh at the miscommunication happening here.  Otherwise I'd
>> get
>> >> frustrated.  I was not trying to say it was a bug in Tapestry.  It's a
>> "bug
>> >> in my code" in the fact that I'm trying to use a nonexistent feature.
>>  And
>> >> I'm NOT suggesting that T5 should replay loops like T4.  Tapestry has
>> moved
>> >> beyond that and I have too.  I am fully aware that Tapestry has
>> introduced a
>> >> number of other features (page activation context, action context, and
>> >> formState) to take the place of replaying loops.  I just haven't found
>> the
>> >> "thing" that handles this particular use case.  It actually might be
>> there
>> >> but I just don't know.  I do have a lack of T5 experience, as you point
>> out.
>> >>  So I am asking to see if anyone on this forum can help me to discover
>> what
>> >> I'm missing.
>> >>
>> >>
>> >
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>
>>
>

Reply via email to