Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

e.preventDefault() on a re-routing system #83

Open
mreis1 opened this issue Aug 8, 2014 · 1 comment
Open

e.preventDefault() on a re-routing system #83

mreis1 opened this issue Aug 8, 2014 · 1 comment

Comments

@mreis1
Copy link

mreis1 commented Aug 8, 2014

As specified at the documentation it's possible to preventDefault the $.mobile.pageChange() and resolve it as soon as we want.

So, because my application keeps most of it's UI structure in all diferent views, like header and sidebar, I decided to create the following approach.

at index.html

<div data-role="page" class="type-interior" id="page1">
   <div class="header">foo</div>
   <div class="placeholder">bar</div>
</div>
<div data-role="page" class="type-interior" id="page2">
      <div class="header">foo</div>
      <div class="placeholder">bar</div>
</div>
<div data-role="page" class="type-interior" id="page">
          <h1>This page is never shown</h1>

            I intersect any changePages to this router and based on the last active page(#page1 or #page2) I update the content into the next.

          <!--  -->
</div>

at router.js

var myRoutes = [
    //...other routers to other pages like #login ...
    { "#page":      { handler: "pageBc", events: "bC", argsre: true }},
    //views will be toggled between this 2 pages
    { "#page1":      { handler: "dynamicView", events: "bC", argsre: true }},
    { "#page2":      { handler: "dynamicView", events: "bC", argsre: true }},
];

var myHandlers = {
pageBc: function(type,match,ui,page,e){
        e.preventDefault();
        ui.toPage = pageChanger.getNextPage();
        // ui.options.changeHash = "true";
        // ui.options.dataUrl = ui.toPage;
        ui.bCDeferred.resolve();
        console.log("this is an hub view, you are going to be...");
        console.log("...redirected to another view");
    },
    dynamicView: function(type,match,ui,page,e){
        e.preventDefault();
        var params = approuter.getParams(ui["options"]["dataUrl"]);
        var p = params["id"];
        switch (p)
        {
            case "dog":
                console.log("dog");
                myapp.fetchDogs().done(function(data){
                         myApp.renderDogs(data).done(function(){
                            //ok, data is fetched and rendered. We are ready to show the view
                             ui.bCDeferred.resolve();
                         });
                });
                break;
         // ...other possible params passed as id #page?id=dog, #page?id=cats
}

the pageChanger monitors the last JQM page where html data referencing the view
was appended. For example. if we appended data into "#page1 .placeholder" when transtioning to #page?id=dogs, if we change to #page?id=cats our target view will be #page2 (which is response from the pageChanger.getNextPage())

var PageHandler = function(){
    var currentPage = "#page1";
    this.getCurrentPage = function(){
        return currentPage;
    };
    this.getNextPage = function(){
        return updatePage();
    };
    var updatePage = function(){
        if (currentPage == "#page1"){
            currentPage = "#page2";
        } else {
            currentPage = "#page1";
        }
        return currentPage;
    };
};

var pageChanger = new PageHandler();

This solution is great because it solves the visual problem of transitioning to the same page where most of the time we see:

  • the old content being removed from the view before the transition starts
  • and because sometimes the content is appended before or long time after the transition ends
  • also, this prevents me from replicating the same view over and over again like so:
<div data-role="dog" class="type-interior" id="page2">
      <div class="header">foo</div>
      <div class="content">
           <ul class="sidebar">
                <li>
               <a href="#dogs"></a>
                </li>
                <li>
               <a href="#cats"></a>
                </li>
               <!-- other links -->
           </ul>
          <placeholder></placeholder></div>
</div>
<div data-role="cats" class="type-interior" id="page2">
     <!--same structure of dogs and all other sidebar items -->
</div>
  • I can preventDefault the event from #page router handler, getNextPage() and update the toPage resolving the $.Deferred to execute the redirection.
  • I CAN'T prevent the event of the redirected page and resolve the deferred later.

Any help please?

@mreis1
Copy link
Author

mreis1 commented Aug 8, 2014

After digging into the problem by starting a simple project to ensure that only essencial code was part of the content I realize that the problem report above is not, somehow, caused by my code.

I did this Demo where I achieved the desired task
https://github.com/mreis1/jqmrouter-singlepage

Anyway during the development of that demo i detected another problem with deferred transitions. For example, If we click on link whose router handler is preventing the page transition for something like 2 seconds (just an example), If I click on second link during the those 2 seconds we'll face one of the following problems:
a) if the second link takes lesser than 2 seconds to navigate to the target page we will be redirected to the second link and when the first link gets resolved, we are taken to it's content.
b) if the second link takes longer than 2 seconds the problem will be the opposite. First we are taken to the first page and then right after to the second page

Probably the default desired behavior would be cancel any ongoing deferreds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant