jQuery Mobile seems to assume that content is either stored locally in existing HTML, or rendered server-side as HTML, delivered via Ajax. Instead, I'd like to render client-side using a templating engine (Mustache/Handlebars) and JSON data.
I have a solution cobbled together below, but it lacks some of jQM's benefits, such elegant handling of slow or failed Ajax calls, and automatic purging of old DOM elements to reduce memory usage. It generally feels a little hacky.
Is there a better way to do this? jQM doesn't seem to have any "hooks" in changePage() or loadPage() for doing custom rendering.
<div class="app">
<div data-role="page" id="main">
<a href="#mypage1">one</a>
<a href="#mypage2">two</a>
</div>
<div data-role="page" id="mypage1"></div>
<div data-role="page" id="mypage2"></div>
</div>
<script type="text/javascript">
$(document).live('pagebeforechange', function(e, page)
{
// If this is a URL request and not an existing DOM
// element, capture page id from URL anchor
if(typeof page.toPage !== "string") return true;
var id = page.toPage.split("#")[1];
// Ensure it's a dynamic page, otherwise handle normally
if(!id || (id != "mypage1" && id != "mypage2") )
return true;
// Pull JSON data from API, and store XHR object
window.currentAjax = $.getJSON("/my/api.json", function(json)
{
// Prevent concurrent requests
if(window.currentAjax) window.currentAjax.abort();
// Insert arbitrary template rendering here
var htmlString = myRenderingFunction(json);
$("#"+id).html(htmlString);
// Wait for DOM to update before transitioning
setTimeout(function(){
$.mobile.changePage($("#"+id), {transition: 'slide'});
}, 30);
window.currentAjax = false;
});
e.preventDefault();
return false;
});
</script>