From 1c053d9f71a822a83214918b8bda9b71a84b0b21 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Tue, 17 Jan 2012 13:54:42 -0500 Subject: [PATCH] Fixes #567 ... Adds a view. for the jQuery cached reference to a view's element ... and this.setElement() as a way to easily change it, redelegating events. --- backbone.js | 23 +++++++++++++++-------- test/view.js | 10 +++++----- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/backbone.js b/backbone.js index fa0dba720..4f30a981e 100644 --- a/backbone.js +++ b/backbone.js @@ -945,7 +945,7 @@ // jQuery delegate for element lookup, scoped to DOM elements within the // current view. This should be prefered to global lookups where possible. $ : function(selector) { - return (selector == null) ? $(this.el) : $(selector, this.el); + return $(selector, this.el); }, // Initialize is an empty function by default. Override it with your own @@ -962,7 +962,7 @@ // Remove this view from the DOM. Note that the view isn't present in the // DOM by default, so calling this method may be a no-op. remove : function() { - $(this.el).remove(); + this.$el.remove(); return this; }, @@ -978,6 +978,13 @@ return el; }, + setElement : function(element, delegate) { + if (_.isString(element)) element = $(element)[0]; + this.el = element; + this.$el = $(element); + if (delegate !== false) this.delegateEvents(); + }, + // Set callbacks, where `this.events` is a hash of // // *{"event selector": "callback"}* @@ -1005,16 +1012,16 @@ method = _.bind(method, this); eventName += '.delegateEvents' + this.cid; if (selector === '') { - $(this.el).bind(eventName, method); + this.$el.bind(eventName, method); } else { - $(this.el).delegate(selector, eventName, method); + this.$el.delegate(selector, eventName, method); } } }, // Clears all callbacks previously bound to the view with `delegateEvents`. undelegateEvents : function() { - $(this.el).unbind('.delegateEvents' + this.cid); + this.$el.unbind('.delegateEvents' + this.cid); }, // Performs the initial configuration of a View with a set of options. @@ -1038,9 +1045,9 @@ var attrs = getValue(this, 'attributes') || {}; if (this.id) attrs.id = this.id; if (this.className) attrs['class'] = this.className; - this.el = this.make(this.tagName, attrs); - } else if (_.isString(this.el)) { - this.el = $(this.el).get(0); + this.setElement(this.make(this.tagName, attrs), false); + } else { + this.setElement(this.el, false); } } diff --git a/test/view.js b/test/view.js index aa9664987..b6e67eb44 100644 --- a/test/view.js +++ b/test/view.js @@ -15,7 +15,7 @@ $(document).ready(function() { }); test("View: jQuery", function() { - view.el = document.body; + view.setElement(document.body); ok(view.$('#qunit-header a').get(0).innerHTML.match(/Backbone Test Suite/)); ok(view.$('#qunit-header a').get(1).innerHTML.match(/Backbone Speed Suite/)); }); @@ -39,9 +39,9 @@ $(document).ready(function() { test("View: delegateEvents", function() { var counter = counter2 = 0; - view.el = document.body; + view.setElement(document.body); view.increment = function(){ counter++; }; - view.$().bind('click', function(){ counter2++; }); + view.$el.bind('click', function(){ counter2++; }); var events = {"click #qunit-banner": "increment"}; view.delegateEvents(events); $('#qunit-banner').trigger('click'); @@ -58,7 +58,7 @@ $(document).ready(function() { test("View: delegateEvents allows functions for callbacks", function() { view.counter = 0; - view.el = "#qunit-banner"; + view.setElement("#qunit-banner"); var events = {"click": function() { this.counter++; }}; view.delegateEvents(events); $('#qunit-banner').trigger('click'); @@ -72,7 +72,7 @@ $(document).ready(function() { test("View: undelegateEvents", function() { var counter = counter2 = 0; - view.el = document.body; + view.setElement(document.body); view.increment = function(){ counter++; }; $(view.el).unbind('click'); $(view.el).bind('click', function(){ counter2++; });