-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
View hooks for native and non-jQuery libraries #3003
Conversation
…nts for easier overriding
Do the other interested parties agree that these hooks are the minimal surface area required to implement a NativeView in a fashion that's optimally performant? |
👍 |
@akre54 I like how you just copied 99% of my PR and stamped your own name on the copyright there :) The event listener shims are slower because of the extra function calls and branching. |
Also, there needs to be a |
And if you make |
Yeah its just boilerplate from one of my other plugins. I credited you in The more important thing is if this PR (and the native view plugin) works The shims are only used in History, which shouldnt be a hot code path. In
|
That's true if you've decided to not bank on the shims to pull out a native BaseView. |
I thought about this, but being able to set |
@@ -1448,7 +1472,11 @@ | |||
// Disable Backbone.history, perhaps temporarily. Not useful in a real app, | |||
// but possibly useful for unit testing Routers. | |||
stop: function() { | |||
Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl); | |||
if (this._hasPushState) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a reason I appended && window.onpopstate
here. This broke IE<=7
Mmmm, |
Eh? As I said in #2959, plugins should rely on |
@jdalton whoah, didn't know you could pass html directly into createElement. Awesome. |
We'd still need the IE sniff for the off hashChange, right? |
Ya, I removed the UA sniff not the
That's why it's wrapped in a try-catch. That syntax is only supported in IE < 9. |
Yup, got it. Neat little old feature. |
|
||
// Cross-platform `addEventListener`. | ||
var addEventListener = function(obj, eventName, listener) { | ||
if (obj.addEventListener) return obj.addEventListener(eventName, listener, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for return
use in addEventListener
and removeEventListener
helpers or use them and drop the else
@akre54 @jdalton Can you guys just clean up History and leave View alone for now? think we can all agree on removing jQuery from History. I'm gonna remove all the shims and changes in History in #2959 and experiment a little with BaseView to iron out a minimal set of hooks to expose that doesn't break things. |
Also, @akre54 If you don't use |
if (!this.options.silent) return this.loadUrl(); | ||
}, | ||
|
||
// Disable Backbone.history, perhaps temporarily. Not useful in a real app, | ||
// but possibly useful for unit testing Routers. | ||
stop: function() { | ||
Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl); | ||
// Cross-platform `removeEventListener`. | ||
var removeEventListener = function(obj, eventName, listener) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as @jdalton said, but here's an even better optimization:
var removeEventListener = window.removeEventListener ||
function (eventName, listener) {
return detachEvent('on' + eventName, listener);
};
removeEventListener('popstate', this.checkUrl, false);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll still want to pass the false
for the third argument to addEventListener
and removeEventListener
as it was not optional Firefox < 6.
No need for .call(window)
; you can also change this.detachEvent
to be detachEvent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Snippet fixed.
I can open another pull, but I think these are part and parcel to the same concept. Might as well merge 'em together or leave them both out.
We do, in #2959 takes the opposite tack with View as this one. Are there any speed problems with this strategy in your eyes? |
@wyuenho moving History hooks to a new PR, and turning this one into just View. |
Some minor nits addressed in akre54#19. |
Return undefined from delegate
* Rename #_remove as #_removeElement. * Add #_setAttributes instead of using #setElement. * Slim down tests a bit. * #delegate returns this.
A little clarification.
Add #_setAttributes and clean up #setElement.
Alright, this is looking good. The final consensus is view subclasses that do not use an API conforming to
@jashkenas Note the addition of
Many thanks to @akre54, @wyuenho, and others for their patience with me, I know we covered a lot of ground here. 😃 👍 |
Huge 👍 for this work. It will be really exciting to see how this influences Backbone frameworks. |
Thanks for all of your work on this. Already have immediate plans for it as soon as it is ready: |
View hooks for native and non-jQuery libraries
Anyone feel like adding a page to the wiki for library developers explaining how to take advantage of the full implications of this patch? |
Heads off to @paulmillr for the initial PR too. Thanks everyone for helping out with this! @jashkenas Since we'll have to document the new APIs anyway, shouldn't we add a section to the FAQ instead? |
This has been a fantastic pr to follow. Thanks to all participants striving to make this project better. |
Yeah I can write something up for the wiki or docs. Nice job everybody. This was one crazy long PR! |
This is a continuation of the discussion in #2959, and focuses on making View easier to extend by users wishing to use non-jQuery libraries. It's similar in plugability to
Backbone.ajax
or other overridable parts of Backbone.Native Views and non-jQuery DOM libraries would be able to create a native View implementation by overriding
$
,make
,remove
,setElement
,delegate
, andundelegateEvents
(see the NativeView reference implementation). This preserves the majority of the public contract of View (with the notable exception ofView#$
andview.$el
), and the public interface of the constructor (including passing options),delegateEvents
/undelegateEvents
,render
,remove
, andsetElement
would be virtually unchanged. The PR also re-addsView#make
.The next step would be to remove Backbone.$() calls from History and perhaps extend
View#setElement
andView#make
to use a common exposedcreateElement
utility.Update for folks tuning in late: The final list of overridable methods is available on the wiki with instructions for how to use it in your own project.