![]() |
|
Snippets |
|
Quentin Garnier, in this snippet: http://www.symfony-project.com/snippets/snippet/57, suggested a way to have a link call multiple remote functions (with "in order" calls being enforced by a new 'wait' parameter). With a slightly modified version of his code, here are a few more functions to be added to you Javascript.php function in the symfony core:
function periodically_call_remotes($options = array()) { $frequency = isset($options[0]['frequency']) ? $options[0]['frequency'] : 10; // every ten seconds by default $code = 'new PeriodicalExecuter(function() {'.remote_functions($options).'}, '.$frequency.')'; return javascript_tag($code); } function link_to_remotes($name, $options = array(), $html_options = array()) { return link_to_function($name, remote_functions($options), $html_options); } function remote_functions($options) { // Multi ajax call $multi_function = ""; // First pass (wait) for ($i = 0; isset($options[$i]); $i++) { if (isset($options[$i]['wait']) && $options[$i]['wait'] != $i && isset($options[$options[$i]['wait']])) { if (isset($options[$options[$i]['wait']]['complete'])) { $options[$options[$i]['wait']]['complete'] .= '; ' . remote_function($options[$i]); } else { $options[$options[$i]['wait']]['complete'] = remote_function($options[$i]); } } } // Second pass for ($i = 0; isset($options[$i]); $i++) { if (!(isset($options[$i]['wait']) && $options[$i]['wait'] != $i && isset($options[$options[$i]['wait']]))) { $multi_function .= remote_function($options[$i]) . ';'; } } return $multi_function; }
To use it, you could do something like this:
<?php echo link_to_remotes('multi ajax', array( array( 'update' => 'first_zone', 'url' => '/module/action1', 'loading' => "Element.show('indicator')" ), array( 'update' => 'second_zone', 'url' => '/module/action2', 'wait' => 0 /* update in a second server call, after 'news_zone' returns */ ), array( 'update' => 'third_zone', 'url' => '/module/action3', 'wait' => 0 ), array( 'update' => 'fourth_zone', 'url' => '/module/action4', 'complete' => "Element.hide('indicator')", 'wait' => 2 /* update in a third server call, after 'third_zone' returns */ ) ) ) ?>
or this:
<?php echo periodically_call_remotes('multi ajax', array( array( 'frequency' => 60 /* every 60 seconds, frequency only needs to be specified in first call, not subsequent calls */ 'update' => 'first_zone', 'url' => '/module/action1', 'loading' => "Element.show('indicator')" ), array( 'update' => 'second_zone', 'url' => '/module/action2', 'wait' => 0 /* update in a second server call, after 'news_zone' returns */ ), array( 'update' => 'third_zone', 'url' => '/module/action3', 'wait' => 0 ), array( 'update' => 'fourth_zone', 'url' => '/module/action4', 'complete' => "Element.hide('indicator')", 'wait' => 2 /* update in a third server call, after 'third_zone' returns */ ) ) ) ?>
Notes
It should be noted that using the 'wait' parameter will cause all top level ajax remote function calls to be executed in one call to the server, and each second level to be executed in a second call, etc. Basically, multiple calls to the server are generated by the user action.
This will cause huge performance issues if you attempt to use these functions in a high-traffic scalable-sensitive system. It is mainly intended for a link which executes two or three functions at most. To do more, you should consider using another approach, like the JSON approach documented in the wiki.
Comments on this snippet
I made the same comment in the other snippet and I repeat it here: I strongly discourage this technique, because it is not good for the user experience, not good for the server, and way too complicated.
If you want to have one remote call update multiple divs, then the result of the remote call must be a list of
update_element_function()calls. This means that there will only be one single remote call, and that the update will be fast and effective, in a word: user-friendly.See "Notes" section, which states I am aware of such fallbacks. The use of every approach has reasoning behind it. As educated computer scientists, we can chose when extremes are necessary, and when they aren't.