Saving and restoring page state in a WinJS application

Published November 15, 2013 1:39 pm

When building a winjs application with multiple pages, there is high chance that you need to save and restore page state of some of the page(s).

First – what is page state and why it needs to be saved & restored? Let’s take few example cases.

  1. User inputs some data provided in a form page. When the form page is navigated back, form page needs to be filled with the same data; not lose data.
  2. Page contains a list view with multiple items; user scrolls to reach an item and clicks it to traverse to the item detail page. When user navigates back, list view’s scroll position should not be reset.
  3. Add another case for case (2). application is suspended when on the item detail page, restored during next activation and start on item details page. In such case also, the listview scroll position should not be lost when navigating back to the list view page.

How to handle this?

In a WinJS application, each page is re-initialized when navigated back. ready event handler is called each time a page is navigated. Hence, to keep the page in the same state – it’s state needs to be saved and restored. WinJS library provides WinJS.Application.SessionState object. It is serialized and de-serialized across application suspension by the library. The page state needs to be saved and restored to/from session state object.

What the code looks like? Let take the case (2).
Initializing, and restoring the scrollPosition state on the list view

 
    var sessionState = WinJS.Application.sessionState;
    ready: function onready(element, options)
    {
        ...
        if (!sessionState.itemList)
            sessionState.itemList = {};
        else if (sessionState.itemList.scrollPosition)
        {
            WinJS.Promise.timeout().then(function ()
            {
                listView.winControl.scrollPosition = sessionState.itemList.scrollPosition;
            });
        }
    },

Saving the scrollPosition state when navigating to the item detail page. The code below is doing that in the iteminvoked handler.

 
    listView.winControl.addEventListener('iteminvoked', function (event)
    {
        var item = this.viewModel.items.getAt(event.detail.itemIndex);
        sessionState.itemList.scrollPosition = textListView.winControl.scrollPosition;
        WinJS.Navigation.navigate('/pages/itemDetail/page.html', { item: item });
    }.bind(this));

That’s it. Few comments before closing.

  1. It will be good practice to keep separation between the state for each page. Hence, the code above saves the scrollPosition state for the itemList page under itemList property in session state object.
  2. The state is restored typically in the ready handler.
  3. The state needs to be saved prior to the navigation to the next page.
  4. scrollPosition is restored under a setImmediate call. otherwise, it does not get restored.

HTH.

Leave a comment