-
Notifications
You must be signed in to change notification settings - Fork 255
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
Idea: Route events #93
Comments
I've been using History.js for my Aura routing. I tried augmenting Backbone's built-in routing, but it turned into kind of a rabbit hole I didn't want to dive down at the time. I think if we could get that to work with Aura, it would be ideal, so I may sit down again and see if I can get it up and running. |
@dustinboston In order for routes to publish events, wouldn't we have to either generalize the routing to outside a framework or only implement this in the backbone-aura extension? Did you have a POC that describes this concept better in mind that you might be able to share? |
Better fit as an extension or use of a routing lib directly IMHO. |
@addyosmani Would it not make more sense to treat routes as another widget? This prevents the use case of two widgets implementing the same route potentially as well as centralizing all routing. You also get the described feature of Routes having events. |
So what are routers in front end js. Let's be good scholars and dig in :D
var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
if (oldIE) {
this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
this.navigate(fragment); // ancient ie just navigates to fragments.
}
// cross-browser events against window's popstate and hashchange
if (this._hasPushState) {
$(window).bind('popstate', this.checkUrl);
} else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
$(window).bind('hashchange', this.checkUrl);
} else if (this._wantsHashChange) {
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
} Insight:
This is where it gets complicated. We have 3 components:
Backbone.history handles the hash changes. // cross-browser events against window's popstate and hashchange
if (this._hasPushState) {
$(window).bind('popstate', this.checkUrl);
} else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
$(window).bind('hashchange', this.checkUrl);
} and poll with else if (this._wantsHashChange) {
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
}
checkUrl: function(e) {
var current = this.getFragment();
if (current == this.fragment && this.iframe) current = this.getFragment(this.getHash(this.iframe));
if (current == this.fragment) return false;
if (this.iframe) this.navigate(current);
this.loadUrl() || this.loadUrl(this.getHash());
},
loadUrl: function(fragmentOverride) {
var fragment = this.fragment = this.getFragment(fragmentOverride);
var matched = _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment); // it's hitting a callback function
return true;
}
});
return matched;
},
Where does the Router come in to play?var Workspace = Backbone.Router.extend({
routes: {
"help": "help", // #help
"search/:query": "search", // #search/kiwis
"search/:query/p:page": "search" // #search/kiwis/p7
},
help: function() {
...
}
search: function(query, page) {
...
}
route: function(route, name, callback) {
Backbone.history || (Backbone.history = new History);
if (!_.isRegExp(route)) route = this._routeToRegExp(route);
if (!callback) callback = this[name];
Backbone.history.route(route, _.bind(function(fragment) {
var args = this._extractParameters(route, fragment);
callback && callback.apply(this, args);
this.trigger.apply(this, ['route:' + name].concat(args));
Backbone.history.trigger('route', this, name, args);
}, this));
return this;
}, So as of Backbone 0.9.2, the router verifies initialization of Backbone.History into Backbone.history. If it's not initialized, it does it now. Then it will use underscore method _.isRegExp to see if the route is a RegExp object. The It will use _.bind(function(fragment) {
var args = this._extractParameters(route, fragment);
callback && callback.apply(this, args);
this.trigger.apply(this, ['route:' + name].concat(args));
Backbone.history.trigger('route', this, name, args);
}, this) This dance is wrapping the callback to accept the parameter arguments and trigger a history event. And making sure to bind it against Backbone.Router's instance context - as it's being accessed from Backbone.history. With the context binded,_extractParameters can be utilized against the reference to
route: function(route, callback) {
this.handlers.unshift({route: route, callback: callback});
}, So when Backbone.history detects a hashchange, with all of the parameters extracted as an argument, which are then passed in via passes out edit: fixes. |
hands glass of water to Tony Are you better? |
POC for routing in branch https://github.com/tony/aura/tree/history.
Trigger Above:
The widget is called router. It has no DOM object on the page being used, but one is being passed to prevent error. The lambda in
The Calendar widget
|
I can't believe I almost missed this. That's really awesome work @tony :) I also really appreciate all of the research work you put into figuring out a good routing strategy. If we could add a routing support example for the Todo widget as well (e.g https://github.com/addyosmani/todomvc/tree/gh-pages/architecture-examples/backbone) I'd be happy with us merging your POC in :) |
thank you @addyosmani . sounds like a plan. |
@addyosmani just a pulse, router poc is alive using router pattern from that repo. will pr tomorrow when todo is wired in. |
Awesome! :) |
@tony is there anything else we're waiting on for this issue or is it good to close? :) |
Closing due to age and relevance to direction in master. |
From the last catch-up @dustinboston and I had about the project:
The text was updated successfully, but these errors were encountered: