Question

I have an iphone-style list-view system for navigation of a website that looks like this:

How it should appear

The URL is changed dynamically when a panel is loaded via AJAX and the same URL is placed in the browser address bar with puststate. This a allows a page refresh to reload the current page:

this.Historyjs.pushState({}, "", url);

To make this work the pages can return themselves as either a partial page, or a full page. The code to detect the difference is a base controller and looks like:

    public bool IsPartialPage
    {
        get
        {
            // ListViewer will strip out HTML from a full page if this occurs
            return Request.IsAjaxRequest() || !string.IsNullOrEmpty(Request["partial"]);
        }
    }

An example controller action looks like this (note the Partial View cache expiry):

    [OutputCache(Duration=1)]
    public ActionResult ListViewerDocumentation()
    {
        if (!base.IsPartialPage)
        {
            ViewBag.Layout = "~/Views/Shared/_ListViewLayout.cshtml";
        }
        return PartialView();
    }

The problem I have is that when you navigate using the Browser's back and forward buttons, it will occasionally decide that a previously partial page is sufficient to become the entire page and does not make a call to the server (checked with Fiddler2) and so looks like this:

How it appears after random Back/Forward

Any suggestions on a method that will ensure back and forward navigation always pull back a full page and not from its cache of Ajax requests? Is it simply a matter of making the Ajax calls unique, or will the vanilla URL from the back/forward still match?

Was it helpful?

Solution

Turns out the trick is to turn off caching on the Ajax request that pulls the partial pages, not on the server as that is never hit (the light suddenly came on after writing the above question):

   $.ajax(
            {
                cache: false,     // << Added this
                url: url,
                type: "GET",
                error: function (jqXHR, textStatus: string, errorThrown: string)
                {
                    // On error (eg. "not found") empty out the display
                    THIS._removeContent();
                },
                success: function (data: string, textStatus: string, jqXHR)
                {
                    var $data = $(data);
                    THIS._insertContent($data, function ()
                    {
                    });
                }
            });

The cache false also apparently ensures the browser will not reuse the page on page back/forward operations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top