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

restore support for string ui.toPage in pagebeforechange events #76

Closed sheppard closed 11 years ago

sheppard commented 11 years ago

Hi, I see why you disabled support for ui.toPage being a string in pagebeforechange events - but this is actually my primary use case for jQM router. I've been building a custom jQM-based offline-capable web app framework called wq.app. wq.app includes the ability to automatically render and inject pages offline in response to URL changes, via cached JSON objects and interned Mustache templates. My bC callback (pages.register / pages.go in pages.js) responds to pagebeforechange events by rendering and injecting pages into the DOM - so I don't need the actual page object in my case (since I know it doesn't exist yet).

I understand that this might be a case for implementing my own pagebeforechange handler, but I really would like to take advantage of jQM router's URL matching capabilities, since I am registering multiple URL-specific callbacks to handle template selection and context generation.

This pull request restores support for string ui.toPage in bC events to jQM router, with the understanding that the page object may not be defined in this case. Since this is somewhat advanced and may not apply to everyone, I added a configuration option to enable this behavior and set it to false by default. I called the new option "bCAllowStringPage", though I'm certainly open to suggestions for a better name.

azicchetti commented 11 years ago

I was wondering the same thing when I decided to call bC handlers just once when ui.toPage is a jQuery object and I guess we need a more fine-grained control over this event.

I was planning a per-route option, something to specify what kind of ui.toPage your handler is expecting and whether you want the router to expose the deferred object (thus calling e.preventDefault for you).

Then your pull request came in and now I'm wondering if I was just overcomplicating things. With your simple global configuration, the user can still have all the flexibility he needs without tons of options in his routes. With a little coding on his part, all the use cases I can think of can be covered.

What do you think about all this? I guess you have a lot of expertise on the subject, I could really use your advice right now ;)

azicchetti commented 11 years ago

Hi, I've added the "step" option to pagebeforechange routes in order to choose what kind of data.toPage parameter the handler is expecting.

Starting from version 20130525, the user needs to explicitly call e.preventDefault() in bC events in order to use the deferred object.

I think these patches should fix your problem and also offer more flexibility to the developer.

sheppard commented 11 years ago

Thanks, your approach makes sense and is probably more useful than my global option, since this is really something each route may need to handle differently. I'll try it out when I get a chance - I've been busy with FOSS4G-NA and other things, sorry I didn't get back to you sooner.

As I thought about this more I am wondering if the two pagebeforechange steps should really split be two separate events given the different use cases and callback values. I will try to bring this up with the jQM developers next time I'm on IRC. What do think about this, and do you have any thoughts on a potential name for the new event? (Best I've come up with so far is pagebeforebeforechange :stuck_out_tongue_closed_eyes: )

I am also wondering if pagebeforeload is really the event I should connect to for my specific use case (in pages.register()), since the jQM code I am trying to override is the code that loads html from the server in response to a url change. Have you done much with pagebeforeload?

azicchetti commented 11 years ago

The whole pagebeforechange event seems quite a mess to me, and I'm under the impression that I'm not the only one struggling with it.

jQM 1.3 has been a huge leap forward, especially for the partial support for hash parameters, but there's stll something strange about this event. I have four major complaints:

I don't know if splitting the event in half would help us, it's not that much of a trouble to check the toPage argument, provided they address all the other issues first :-D

I completely forgot in my previous answer to comment on your nice project, wq,app.

The first thing that came to me when I saw the code was in fact using the pagebeforeload event, 'cause it's specifically designed to inject pages and override the whole ajax mechanism built in jQM. The deferred thing is a plus here, it seems a really clean way to handle the whole mess (in fact I've tried to port its basic idea to pagebeforechange). Too bad pagebeforeload is not available for single-file multipage applications (this would probably solve a lot of problems), but it shouldn't be an issue for wq.app, since you're using the ajax schema.