Re: RR loop confusion....
Re: RR loop confusion....
- Subject: Re: RR loop confusion....
- From: "Jerry W. Walker" <email@hidden>
- Date: Tue, 26 Jul 2005 00:37:32 -0400
Hi, Florijan,
The short answer to your question is that WOComponents and
WODynamicElements are active objects who each determine their own
responses to takeValuesFromRequest, invokeAction and
appendToResponse. They can't do so unless they are each called during
each of the three phases of the RR loop (with the exception that
during invokeAction, the elements are messaged in turn till one
responds with a non-null result, then none of the rest are called
since there can be only one action method invoked for the phase).
The longer answer is that for EACH PHASE of the RR loop, WO builds an
HTML tree graph of the page called the component template. The nodes
on this tree are the WOComponents (subcomponents), WODynamicElements
and the chunks of static HTML that intervene. When
takeValuesFromRequest is sent to WOApplication, it sends it on to
WOSession who passes it on to the root of this template. The root
passes it on to each of its children and so on recursively in a depth
first transit of the entire tree.
EACH component and dynamic element on the tree are provided with the
WORequest containing the form values and the WOContext (even if they
were not contained within the form). Each of the nodes on the
template are numbered uniquely within the template. As they receive
the takeValuesFromRequest message, they can each determine their
unique element ID. If their ID matches that of one of the values in
the form, they are responsible for actively taking the value and
doing something with it (e.g. formatting it if a formatter is
involved, or simply stuffing it into one of their variables).
If none of the values matches their component ID, they are still
responsible for passing the takeValuesFromRequest message along the
tree. So each element of the entire page must be activated during
this phase.
The story is very similar for invokeAction, except when an element
recognizes that it is the target of the action, it returns a non-null
value and that stops the invokeAction cycle (since that guarantees
that no other elements will care).
As an aside, this is a good reason for returning context().page()
instead of null in an action method that wishes to return the current
page. By returning context().page(), the invokeAction stops right
there. If the action method returns null, then the invokeAction is
visited on every node in the template to determine that none of them
will provide a response. The default action in this case is the same,
to return the current page, but every node must be visited first in
the latter case.
A similar sequence occurs with appendToResponse. The template is
generated, each node is visited and each appends its piece to the
HTML response.
The upshot is that the elements of the template are ALL referenced
(except in invokeAction) and actively take and/or do what they need.
If they don't need anything in this phase of the RR loop, then they
simply pass the call along to the next element of the tree.
If my longer answer wasn't sufficient and you want more details on
this process, Chuck & Sacha cover it very well in Practical
WebObjects in their Chapter 6 on "The Secret Life of Components".
One other point to make here is the absolute need to avoid any side
effects that would change the structure of the component template
from the page's initial appendToResponse until the subsequent
takeValuesFromRequest and invokeAction for that page both complete.
If anything would cause that structure to change (such as changing
the boolean value on which a WOConditional depends, or changing the
size of an array over which a WORepetition increments), then some
elements in the component template will be given the wrong component
ID, so they will act on the wrong values. This is a common and
PERNICIOUS error in WO applications.
It sounds like this is the problem you're having as you've outlined
in your "Skippable details:" section.
Hope this helps.
Best regards,
Jerry
On Jul 25, 2005, at 1:57 PM, Florijan Stamenkovic wrote:
Hi all...
Bumped into something I really can not figure out. Any help would
be greatly appreciated.
I got a repetition that has a list binding to a method returning
NSArray. Method is called resultsPerPage(). After logging the RR
loop I saw that the resultsPerPage() method gets called in just
about every stage of the loop. If I clicked on a submit within a
form, it gets called in takeValuesFromRequest (the repetition the
method is bound to is NOT within the form), in invokeAction, and
finally in appendToResponse... Why??? Not to mention that the
methods that are invoked (component actions) do not invoke it. The
only binding / invocation is the repetition itself (checked).
/*************
Skippable details:
The problem became visible when I started using NSRange within the
resultsPerPage(). It throws exceptions because it's second argument
is negative. The cause of that is that resultsPerPage() is using
two variables: delimiter(how many results per page) and
currentPage. The problem appears because delimiter can be changed
during takeValuesForRequest as it is bound to a text field. The
currentPage gets reset to 1 during invokeAction, a precaution taken
not to end up with attempting to display a page that actually is no
longer there (if the update delimiter is so big that there is no
need for so many pages). The delimiter is in a form that has a
single button that is bound to a method that resets the currentPage
to 1. So, it is impossible to change the delimiter without invoking
that particular method. However, as the resultsPerPage() method
gets called before invokeAction(), the delimiter is updated to a
different value, but the currentPage is still on the old value,
what can result in gibberish values when determining the range of
the array that should be returned as a subarray of the bigger,
cached array..
********/
So, how come that a key method gets invoked so many times during
the RR loop?? Does anybody have a better solution to having a
dynamically resolved subset of a search query?
TIA
Flor
oh - just to note that I have used this a lot now, but not
utilizing NSRange, but by copying manually records into a
NSMutableArray, and checking that I am not out of bounds. Which of
course resulted in an empty array in all the RR stages before the
response were really generated, but that didn't throw any
exceptions. The generated response had all the numbers right of
cours...
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40codefab.com
This email sent to email@hidden
--
__ Jerry W. Walker, Partner
C o d e F a b, LLC - "High Performance Industrial Strength
Internet Enabled Systems"
email@hidden
212 465 8484 X-102 office
212 465 9178 fax
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden