tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ákos Maróy <dark...@tyrell.hu>
Subject target-page based listener semantics
Date Sat, 02 Dec 2006 08:08:56 GMT
Hi,

I have a question about listener semantics in Tapestry, about how one
could achieve a simple usage semantics, when the target of a link or a
form is a different page / component, than the invoker.

The current typical usage for listeners in Tapestry is that the listener
would be in the same page / component, as source of invocation (the
form, link, etc.) This pattern in encouraged by the listener: binding as
well.

What I would like to have is a pattern where one could simply say that
'I will submit this to page Foo', instead of submitting to 'myself'. For
example, currently a typical Tapestry invocation is something like:

<a jwcid="@DirectLink" listener="listener:fooListener"
parameters="blahblah">link back to myself</a>

whereas if I'm at page Bar, but wold would still like to submit to
fooListener at page Foo, it would be nice to have something like:

<a jwcid="@DirectLink" target="Foo" listener="listener:fooListener"
parameters="blahblah">link to page Foo</a>

of course, one can achieve the above with some magic, specifically:

<a jwcid="@DirectLink"
listener="ognl:requestCycle.getPage('Foo').listeners.fooListener"
parameters="blahblah">link to page Foo</a>

but well, this is obviously a workaround :)

similarly, it would be nice if the target page would define the scope of
form parameter as well. let's take the example:

<form jwcid="@Form" success="listener:fooListener">
<input jwcid="myParam@TextField" value="ognl:myParam"/>
<input jwcid="@Submit"/>
</form>

submits back to the same page. now one could have:

<form jwcid="@Form" target="Foo" success="listener:fooListener">
<input jwcid="myParam@TextField" value="ognl:myParam"/>
<input jwcid="@Submit"/>
</form>

to submit to Foo.fooListener() directly. currently, using the above
workaround it's quite awkward, as for each form parameter one has to
specify the target page as well:

<form jwcid="@Form"
success="ognl:requestCycle.getPage('Foo').listeners.fooListener">
<input jwcid="myParam@TextField"
value="ognl:ognl:requestCycle.getPage('Foo').myParam"/>
<input jwcid="@Submit"/>
</form>


Of course, submitting back to oneself makes sense in a lot of cases, and
has the effect that both the source of invokation and all the processing
of the data is contained in the same page or component.

But, it is a bit contrary to the original concept of hyperlinking, where
one could actually link to an _other_ page, not onto himself. Let's
assume the following scenario:

- I have a page Foo, that displays something based on an input parameter.
- I have a huge amount of pages a that link to Foo, calling it with all
sorts of parameters. Let these be Bar001, Bar002, etc.

Traditionally this would be solved like the following:

- Foo.html would expect parameters either through HTTP GET or POST
- Bar00X.html could either link to it:

<a href="Foo.html?myParam=blahblah">link to Foo</a>

or have a form submit to it:

<form target="Foo.html">
<input type="text" name="myParam"/>
<input type="submit"/>
</from>


And this is all quite usual to do. Now, with Tapestry, all this is very
complicated using the encouraged pattern of having a listener on the
same page / component as the invocation source. Now the solution looks
like is:

- in the page Foo, a one would have a property name myParam
- in the page Bar00X, one would have:
  - a property named myParam
  - an injected property containing a reference to page Foo
  - a listener, doing most of the work:

something like this for _each_ Bar00X:

@InjectPage("FooPage")
public abstract IPage getFooPage();

public abstract Object getMyParam();

public IPage barListener(Object myParam) {
    FooPage fooPage = getFoo();
    fooPage.setMyParam(myParam);
    return fooPage;
}


and then the HTML code would look like:

<a jwcid="@DirectLink" listener="listener:barListener"
parameters="blahblah">link to Foo</a>



My problem with the above scenario is that one has to duplicate the
functionality of the listener for _every_ Bar00X page, including form
data validation, some amount of pre-processing. If we consider that
these might not share the same ancestor, that would enable re-use of
common functions, or that the caller might not even be a Tapestry page,
but say some foreign page, this solution is all too complex, encourages
code duplication, etc., when compared to the simple traditional solution
shown above.



Akos

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Mime
View raw message