Search code examples
javascriptknockout.jssammy.jspagerjs

Sammyjs and pagerjs routes


I'm started using a combination of KnockoutJS (2.2.1), SammyJS (0.7.4) and PagerJS (latest from github with jquery hashchange) to create a single page app and I've run into a problem with the routes as they do not work in Chrome Version 24.0.1312.57 m or Firefox 16.0 (for some reason it actually works in IE7).

Using sammyjs I've specified the routes that the app should react on and their corresponding actions, for example loading user data. The same routes are used in pagerjs to specify which page to display. For some reason the sammyjs code is executed but not the pagerjs code.

When updating the route, for example going from #!/ to #!/user, pagerjs doesn't switch to the new page, but data is updated as expected when switching between #!/user?uid=123 and #!/user?uid=321 . However, when removing the sammyjs code it works - the switch between pages works but data will of course not update properly.

It seems like SammyJS terminates further execution by pagerjs, but as I'm quite new to these libraries it might very well be my code misbehaving. Greatful for any insights.

The javascript code looks something like this:

    var UserModel = function () {

        var self = this;
        self.userId = null;
        self.user = ko.observable();
        self.userid = ko.observable();

        // Load
        self.load = function(userId) {
            self.loadUser(userId);
        };

        // Load user data
        self.loadUser = function(userId) {
        console.log('Loading user data');
        }; 

        // Client-side routes    
        Sammy(function () {

            // Overview - datatables in tabs
            this.get('#!/', function () {
                console.log('Start page');
            });

            // User - details
            this.get('#!/user', function () {
                console.log('user page');
                self.userId = this.params.uid;
                self.load(self.userId);
            });

        }).run();


    }

// Renders user info
$(document).ready(function () {
    if ($('#user-info').length) {
        var userModel = new UserModel(); 
        pager.extendWithPage(userModel);
        ko.applyBindings(userModel);
        // Load initial data via ajax
        userModel.load();
        pager.Href.hash = '#!/';
        pager.startHashChange();
    }
    $('.dropdown-toggle').dropdown();
});

And here goes the HTML with the pagerjs data-bindings:

<div class="container">

    <div data-bind="page: {id: 'start'}">
        Startpage
    </div>

    <div data-bind="page: {id: 'user', params: ['uid']}">
        User page
    </div>

</div>

Solution

  • I've got it working by changing PagerJS to use the naïve history manager instead of jQuery hashchange. In other words this line:

    pager.startHashChange();
    

    was changed to:

    pager.start();
    

    As of magic it also works in IE7 even if the docs at http://pagerjs.com states it doesn't. Well, for me it does work

    // 1. iff using naïve hashchange - wont work with IE7
    pager.start();