[ 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:27 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 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. > 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)