Dynamically injecting page content with Ajax+JSON

Dynamically injecting page content with Ajax+JSON

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.

  1. <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>