I have came up with this neat solution. You first start by creating a namespace for your binders in the global scope:
// Binder for PJAX init functions
$.fn.bindPJAX = {}; // Create namespace
function bindPJAX(functionName) {
// Check function existence, then call it
return $().bindPJAX[functionName] && $().bindPJAX[functionName]();
}
Then bind a callback to PJAX clicks:
$(document).ready(function(){
if ($.support.pjax) {
$('a[data-pjax]').on('click', function(event) {
var container = '#main';
var emptyRoute = 'feed'; // The function that will be called on domain's root
// Store current href without domain
var link = event.currentTarget.href.replace(/^.*\/\/[^\/]+\//, '');
var target = link === "" ? emptyRoute : link;
// Bind href-specific asynchronous initialization
$(document).on('ready pjax:success', container, function() {
bindPJAX(target); // Call initializers
$(document).off('ready pjax:success', container); // Unbind initialization
});
// PJAX-load the new content
$.pjax.click(event, {container: $(container)});
})
}
});
When this is set up, you can proceed to extend the $.fn.bindPJAX
object to add functions that will match your route name. For example, this, in the global scope, will be called when accessing http://www.yourdomain.com/admin
via PJAX:
$.extend($.fn.bindPJAX, {
admin: function(){
// Initialization script for /admin route
}
});
You should also consider a viable DRY fallback when PJAX fails or isn't supported, like launching the correct init function on first pageload by checking window.location
in javascript, or maybe hardcoding it in your application's views.