azicchetti / jquerymobile-router

A router/controller for jquery mobile. Also adds support for client-side parameters in the hash part of the url. The routes handles regexp based routes. This plugin can be used alone or (better) with Backbone.js or Spine.js, because it's originally meant to replace their router with something integrated with jQM.
GNU General Public License v2.0
402 stars 69 forks source link

Routing issues with JQM 1.3.1 and knockout.js #71

Closed ryankscott closed 11 years ago

ryankscott commented 11 years ago

I am having issues with the JQM router occasionally transitioning to pages without a $.mobile.changePage() call or a link being clicked.

What I am expecting is a sequence of page transitions like this:

Page 1 (#Topics) -> Page 2 (#EditTopic) -> Page 3 (#Home)

However, this is what ends up happening:

Page 1 (#Topics) -> Page 2 (#EditTopic) -> Page 3 (#Home) -> Page 2 (#EditTopic)

This final, incorrect page transition doesn't happen on the first occasion, but will repeat on any subsequent calls. I'm not sure how to debug this or what logs I could send, but I'll attach my router variable to see if there is anything obvious there.

Please excuse my horrible coding style, still learning.


var router=new $.mobile.Router([
        { "#Home": { handler: function(matchObj, ui, page, evt){
                        console.log("~~~~~~~~~~~~~~~~~Home before show~~~~~~~~~~~~~~~~~");
                        $.mobile.loading('show');
                        topicListViewModel.init();
                            console.log(page);
                            console.log(ui);
                        }, 
                    events: "s" }},
        { "#AddTopic": { handler: function(){
                            console.log("~~~~~~~~~~~~~~~~~Before show on AddTopic~~~~~~~~~~~~~~~~~");
                            }, 
                        events: "bs" }},
        { "#EditTopic": { handler: function(){
                            console.log("~~~~~~~~~~~~~~~~~Edit topic beforehide~~~~~~~~~~~~~~~~~");
                            }, 
                        events: "bh" }},
        { "#EditTopic": { handler: function(matchObj, ui, page, evt){
                            console.log("~~~~~~~~~~~~~~~~~Edit topic before show~~~~~~~~~~~~~~~~~");
                            console.log(page);
                            console.log(ui);
                            }, 
                        events: "bs" }},
        { "#Topics": { handler: function(matchObj, ui, page, evt){
                            console.log("~~~~~~~~~~~~~~~~~Topic Graph before show~~~~~~~~~~~~~~~~~");
                            var topicID = ui.input.split("=")[1];
                            // TODO: I really don't like this but can't think of a way of fixing it
                            if(topicID != undefined) {
                                localStorage.setItem('topicID', topicID)
                            }
                            else {
                                topicID = localStorage.getItem('topicID');
                            }

                            // Get the voterID
                            if(voterID == null) {getVoterID();}

                            // Check if the bindings exist
                            if(!ko.dataFor($("#Topics"))) {
                                ko.applyBindings(topicGraphViewModel, $('#Topics')[0]);
                            }

                            // Show the loading screen
                            $.mobile.loading('show');
                            // Get the data for the graph and initialise it
                            $.getJSON(apiUrl + "/Topics/" + topicID + "?voterID=" + voterID, function() {})
                                .success(function(jsonData) {
                                    topicGraphViewModel.init(jsonData);
                                    $.mobile.loading('hide');
                                });
                            }, 
                        events: "bs" }},
        { "#Topics": { handler: function(){
                            console.log("~~~~~~~~~~~~~~~~~Topic Graph hide~~~~~~~~~~~~~~~~~");
                            // Stop graph updating
                            clearInterval(topicGraphViewModel.updateTopicScoresInterval);
                        }, 
                    events: "h" }},
        {defaultHandler: { handler: function(type, ui, page) {
            console.log("Default handler called due to unknown route (" 
                + type + ", " + ui + ", " + page + ")");
        },
        events: "s"}}                               
]);
azicchetti commented 11 years ago

Uhm, everything seems fine with this setup.

However, the router can't transition to a page by himself, there must be something that triggers the page change event. Do you use a $.mobile.changePage or window.location.hash="something" somewhere in your code? Is there a chance that knockout does this by his own?

You can try disabling the allowSamePageTransition logic on line 70:

data.options.allowSamePageTransition = false;

Under some rare circumstances, this setting may lead to strange jQM behaviors during transitions.

Can you send me a demo to properly debug the whole thing? Thanks

ryankscott commented 11 years ago

Hi there,

Thanks for verifying that it's not something obvious in the router. I will mail you an example copy of the code.

Thanks

azicchetti commented 11 years ago

Closing this one. Calling $.mobile.changePage() multiple times, then using $.mobile.back() makes jQuery Mobile act crazy