e.preventDefault() on a re-routing system
mreis1 opened this issue · 1 comments
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?
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.