[
https://issues.apache.org/jira/browse/TAP5-2416?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Geoff Callender updated TAP5-2416:
----------------------------------
Description:
In some cases, a component may want to respond to an AJAX event in another
component. For example a component that display a user's name would want to
know when a user-editing component in the same page has successfully updated
the user via AJAX.
In simple pages it can be handled this way: the server-side event handler
bubbles up a "user changed" event up to its container, and the container can
call down to any interested component it contains and the component could use
AjaxResponseRenderer#addRender(...). The container could also bubble up the
event, and so it repeats right up to the page level.
However, in more complex pages this gets clunky and problematic. It would be
nice to use a publish/subscribe mechanism. But should the mechanism be
server-side, or client-side?
**Server-side** has a fundamental stumbling block: the server-side is usually
stateless. An AJAX request can contain enough info to tell its server-side
component what state is required, but typically it would be only enough for
that component. The server-side component could publish its success, but the
subscribing components may not have enough information to correctly reproduce
their client-side's current state and therefore they would be unable to respond
usefully. This has been discussed extensively in TAP5-2383 .
In contrast, the **client-side** knows exactly the state of every component, so
it is the ideal place to do the publish/subscribe.
Quoting from TAP5-2383...
How about a mechanism along these lines:
- give the Zone component a "refreshOnMessage" parameter, specifying a message
string; and
- give AjaxResponseRenderer a publishMessage(String s) method; and
Tapestry could do the rest, client-side: it receives the message string,
identifies all the zone instances that asked to be refreshed when that string
appears, and triggers a refresh of each one.
For example:
- In onSuccessFromPersonForm(), do
ajaxResponseRenderer.publishMessage("personAdded");
- client-side, Tapestry would identify each subscriber, ie. each zone in the
DOM that was created with refreshOnMessage="personAdded"; and trigger refresh
on that zone. It would be a second request, but so what? Asynch is the rule
these days, not the exception.
The most likely use of this mechanism would be for something that shows a count
of persons to update itself: Persons (27), just as in the example that prompted
this JIRA:
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Different-Zone-Update-s-tt5728186.html
.
If there's a need for a context, e.g. personId, then I think we could handle
it. Perhaps ajaxResponseRenderer.publishMessage("personAdded").with(personId).
However, I haven't thought through how to handle it in the subscribing zones.
More thoughts please!
was:
In some cases, a component may want to respond to an AJAX event in another
component. For example a component that display a user's name would want to
know when a user-editing component in the same page has successfully updated
the user via AJAX.
In simple pages it can be handled this way: the server-side event handler
bubbles up a "user changed" event up to its container, and the container can
call down to any interested component it contains and the component could use
AjaxResponseRenderer#addRender(...). The container could also bubble up the
event, and so it repeats right up to the page level.
However, in more complex pages this gets clunky and problematic. It would be
nice to use a publish/subscribe mechanism. But should the mechanism be
server-side, or client-side?
**Server-side** has a fundamental stumbling block: the server-side is usually
stateless. An AJAX request can contain enough info to tell its server-side
component what state is required, but typically it would be only enough for
that component. The server-side component could publish its success, but the
subscribing components may not have enough information to correctly reproduce
their client-side's current state and therefore they would be unable to respond
usefully. This has been discussed extensively in TAP5-2383 .
In contrast, the **client-side** knows exactly the state of every component, so
it is the ideal place to do the publish/subscribe.
Quoting from TAP5-2383...
How about a mechanism along these lines:
- give the Zone component a "refreshOnMessage" parameter, specifying a message
string; and
- give AjaxResponseRenderer a publishMessage(String s) method; and
Tapestry could do the rest, client-side: it receives the message string,
identifies all the zone instances that asked to be refreshed when that string
appears, and triggers a refresh of each one.
For example:
- In onSuccessFromPersonForm(), do
ajaxResponseRenderer.publishMessage("personAdded");
- client-side, Tapestry would identify each subscriber, ie. each zone in the
DOM that was created with refreshOnMessage="personAdded"; and trigger refresh
on that zone. It would be a second request, but so what? Asynch is the rule
these days, not the exception.
The most likely use of this mechanism would be for something that shows a count
of persons to update itself: Persons (27), just as in the example that prompted
this JIRA:
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Different-Zone-Update-s-tt5728186.html
.
If there's a need for a context, e.g. personId, then I think we could handle
it. Perhaps ajaxResponseRenderer.publishMessage("personAdded").with(personId).
However, I haven't thought through how to handle it in the subscribing zones.
> Client-side publish/subscribe mechanism
> ---------------------------------------
>
> Key: TAP5-2416
> URL: https://issues.apache.org/jira/browse/TAP5-2416
> Project: Tapestry 5
> Issue Type: New Feature
> Components: tapestry-core
> Affects Versions: 5.4
> Reporter: Geoff Callender
> Priority: Minor
>
> In some cases, a component may want to respond to an AJAX event in another
> component. For example a component that display a user's name would want to
> know when a user-editing component in the same page has successfully updated
> the user via AJAX.
> In simple pages it can be handled this way: the server-side event handler
> bubbles up a "user changed" event up to its container, and the container can
> call down to any interested component it contains and the component could use
> AjaxResponseRenderer#addRender(...). The container could also bubble up the
> event, and so it repeats right up to the page level.
> However, in more complex pages this gets clunky and problematic. It would be
> nice to use a publish/subscribe mechanism. But should the mechanism be
> server-side, or client-side?
> **Server-side** has a fundamental stumbling block: the server-side is usually
> stateless. An AJAX request can contain enough info to tell its server-side
> component what state is required, but typically it would be only enough for
> that component. The server-side component could publish its success, but the
> subscribing components may not have enough information to correctly reproduce
> their client-side's current state and therefore they would be unable to
> respond usefully. This has been discussed extensively in TAP5-2383 .
> In contrast, the **client-side** knows exactly the state of every component,
> so it is the ideal place to do the publish/subscribe.
> Quoting from TAP5-2383...
> How about a mechanism along these lines:
> - give the Zone component a "refreshOnMessage" parameter, specifying a
> message string; and
> - give AjaxResponseRenderer a publishMessage(String s) method; and
> Tapestry could do the rest, client-side: it receives the message string,
> identifies all the zone instances that asked to be refreshed when that string
> appears, and triggers a refresh of each one.
> For example:
> - In onSuccessFromPersonForm(), do
> ajaxResponseRenderer.publishMessage("personAdded");
> - client-side, Tapestry would identify each subscriber, ie. each zone in the
> DOM that was created with refreshOnMessage="personAdded"; and trigger refresh
> on that zone. It would be a second request, but so what? Asynch is the rule
> these days, not the exception.
> The most likely use of this mechanism would be for something that shows a
> count of persons to update itself: Persons (27), just as in the example that
> prompted this JIRA:
> http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Different-Zone-Update-s-tt5728186.html
> .
> If there's a need for a context, e.g. personId, then I think we could handle
> it. Perhaps
> ajaxResponseRenderer.publishMessage("personAdded").with(personId). However, I
> haven't thought through how to handle it in the subscribing zones.
> More thoughts please!
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)