[
https://issues.apache.org/jira/browse/TAP5-2383?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14121146#comment-14121146
]
Geoff Callender edited comment on TAP5-2383 at 9/4/14 9:26 AM:
---------------------------------------------------------------
The problem with doing this server-side in an AJAX request is that the
server-side components can't react because they don't know their state - their
parameters cannot be filled unless the conduits from their containers are
instantiated, and so on up the tree - so the subscriber components cannot know
their state without reconstructing the entire page, which might not even match
the current client-side state.
Their client-side equivalents, however, exactly know their state. Using my
suggestion, the sequence in your example would be this:
- 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.
was (Author: geoffcallender):
The problem with doing this server-side in an AJAX request is that the
server-side components can't react because they don't know their state - their
parameters cannot be filled unless the conduits from their containers are
instantiated, and so on up the tree - so they cannot know their state without
reconstructing the entire page, which might not even match the current
client-side state.
Their client-side equivalents, however, exactly know their state. Using my
suggestion, the sequence in your example would be this:
- 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.
> Serverside publish / subscribe mechanism
> ----------------------------------------
>
> Key: TAP5-2383
> URL: https://issues.apache.org/jira/browse/TAP5-2383
> Project: Tapestry 5
> Issue Type: New Feature
> Components: tapestry-core
> Reporter: Lance
> Priority: Minor
>
> In some cases, an event in one component should cause an action (eg ajax
> update) in another. When these components are siblings it sometimes gets
> tricky having to pass zone id's around and having one component update the
> other.
> It would be nice to decouple the components with a serverside pub/sub
> mechanism. Here's an initial brain dump on how it could work.
> {code:java}
> public class EditPersonComponent {
> @Parameter
> private Person person;
> @Inject
> private PersonDao personDao;
> @Inject
> private ComponentResources componentResources;
> // lets assume there's a form in the component which gets posted
> void onSuccessFromPersonForm() {
> personDao.save(person);
> componentResources.publish("personUpdated", person); // new method on
> ComponentResources
> }
> }
> {code}
> {code:java}
> public class SomeOtherComponent {
> @Inject
> private AjaxResponseRenderer ajaxResponseRenderer;
> @Property
> private Person person;
> @Inject
> private Zone personZone;
> // new subscribe annotation (and naming convention?)
> @Subscribe("personUpdated")
> void onPersonUpdatedPublished(Person person) {
> this.person = person;
> ajaxResponseRenderer.addRender(personZone);
> }
> }
> {code}
> If this change was made on ComponentResources, we should probably add the
> following to support invoking publish events on the client
> {code}
> Link ComponentResources.createPublishLink(String eventType, Object... context)
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)