jQuery Mobile transitions and AJAX Polling on a MasterPage

938 Views Asked by At

I am trying to use AJAX polling with jQuery to update a span element on a razor MasterPage in ASP.NET MVC3. The page uses the jQuery Mobile 1.0 framework that adorns simple view changes (like navigating from /home to /about) with some sort of "transition" animation.

This is the Javascript code that does the polling, while the "unreadBubble" span is located in the body - both are defined in the MasterPage!

<script type="text/javascript">
$(document).bind("pageinit", function poll() {
    setTimeout(function () {
        $.ajax({ url: "/Notification/GetUnreadNotificationsCount", 
                    dataType: "json",
                    success: function (data) {
                    $('#unreadBubble').text(data.UnreadCount);
                    poll();
                } 
            });
    }, 1000);
});

So, imagine I have a HomeController and a NotificationController that both use the MasterPage and provide an Index view. The AJAX polling works on both views and updates the span every second as expected. As soon as I navigate from one view to another though, the span gets re-initialized with its default value from the MasterPage (empty) and doesn't update anymore. Interestingly the async GetUnreadNotificationsCount method is still called on the NotificationsController repeatedly - the span just doesn't update. I also tried to alert the span tag in JS and it wasn't null or something.

According to the documentation, jQuery Mobile also loads new pages with AJAX to insert this fancy "SWOOSH" transition animation. This seems to somehow disturb the JS/DOM initialization.

Do you have any idea how to resolve this? Should I bind to another event or can I somehow force the span tag to update?

Solution: It was a caching problem! The following did the trick: Add class="command-no-cache" to your page div add the following JavaScript to the MasterPage:

$(":jqmData(role=page)").live('pagehide', function (event, ui) {
if ($(this).children("div[data-role*='content']").is(".command-no-cache"))
    $(this).remove();

});

1

There are 1 best solutions below

5
On BEST ANSWER

I would use the pagebeforeshow to actually bind the event, and pagehide to remove the event.

Did you try that instead of initializing only once in the pageinit event?

UPDATE: some code for example,

 <script type="text/javascript">
 var timer = null;
 $(":jqmData(role=page)").bind("pagebeforeshow", function() {
     timer = setTimeout(function() {
               $.ajax({ url: "/Notification/GetUnreadNotificationsCount", 
                  dataType: "json",
                  success: function (data) {
                     $('#unreadBubble').text(data.UnreadCount);
                  } 
               });
             }, 1000);
 }); 
 $(":jqmData(role=page)").bind("pagehide", function() {
     if (timer != null){
          clearTimeout(timer);
          timer = null;
     }
 });
</script>

Also corrected some other ""mistypes" along the way, have a look and compare to your code!

Hope this helps