Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Jm add compositeview bindto #7

Merged
merged 4 commits into from

2 participants

@jasonm
  • Fixes SwappingRouter spec
  • Adds CompositeView#bindTo, #unbindFromAll. Invokes #unbindFromAll from within #leave.
...assets/javascripts/backbone-support/composite_view.js
((5 lines not shown))
this.remove();
this._leaveChildren();
this._removeFromParent();
},
+ bindTo: function(source, event, callback) {
+ source.bind(event, callback, this);
+ this.bindings = this.bindings || [];
+ this.bindings.push({ source: source, event: event, callback: callback });
+ },
+
+ unbindFromAll: function() {
+ _.each(this.bindings, function(binding) {
@jferris Admin
jferris added a note

Since bindings isn't initialized unless bindTo is invoked, will this cause errors if the view is removed without ever binding to anything?

@jferris Admin
jferris added a note

It looks like we initialize children in the prototype constructor, so you could initialize bindings there, too.

@jasonm
jasonm added a note

I tried to motivate with a failing test, but it turns out _.each(undefined, function(){}); passes silently. I agree that explicitly initializing bindings in the constructor is more clear anyhow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jasonm jasonm merged commit ea5ea57 into from
@ecbypi ecbypi deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
6 CHANGELOG
@@ -1,3 +1,9 @@
+0.3.0
+
+CompositeView provides this.bindTo(source, event, callback) to provide easy
+unbinding with unbindFromAll(). It also invokes unbindFromAll from within
+leave().
+
0.2.0
The version changes the order of when a view has render called on it when
View
14 lib/assets/javascripts/backbone-support/composite_view.js
@@ -1,16 +1,30 @@
Support.CompositeView = function(options) {
this.children = _([]);
+ this.bindings = _([]);
Backbone.View.apply(this, [options]);
};
_.extend(Support.CompositeView.prototype, Backbone.View.prototype, {
leave: function() {
this.unbind();
+ this.unbindFromAll();
this.remove();
this._leaveChildren();
this._removeFromParent();
},
+ bindTo: function(source, event, callback) {
+ source.bind(event, callback, this);
+ this.bindings.push({ source: source, event: event, callback: callback });
+ },
+
+ unbindFromAll: function() {
+ this.bindings.each(function(binding) {
+ binding.source.unbind(binding.event, binding.callback);
+ });
+ this.bindings = _([]);
+ },
+
renderChild: function(view) {
view.render();
this.children.push(view);
View
2  lib/backbone-support/version.rb
@@ -1,3 +1,3 @@
module BackboneSupport
- VERSION = '0.2.0'.freeze
+ VERSION = '0.3.0'.freeze
end
View
21 spec/javascripts/composite_view_spec.js
@@ -163,5 +163,26 @@ describe("Support.CompositeView", function() {
expect($("#test2").size()).toEqual(1);
expect(view.children.size()).toEqual(1);
});
+
+ it("removes any bindings that were bound via bindTo", function() {
+ var model1 = new Backbone.Model({}),
+ model2 = new Backbone.Model({}),
+ eventListener = sinon.spy(),
+ bindToView = new (Support.CompositeView.extend({
+ initialize: function(options) {
+ this.bindTo(options.model1, 'change', eventListener);
+ this.bindTo(options.model2, 'change', eventListener);
+ }
+ }))({
+ model1: model1,
+ model2: model2
+ });
+
+ bindToView.leave();
+ model1.trigger('change');
+ model2.trigger('change');
+
+ expect(eventListener.called).toBeFalsy();
+ });
});
});
View
2  spec/javascripts/swapping_router_spec.js
@@ -4,12 +4,14 @@ describe("Support.SwappingRouter", function() {
var redView = Backbone.View.extend({
render: function() {
$(this.el).text("Red!");
+ return this;
}
});
var blueView = Backbone.View.extend({
render: function() {
$(this.el).text("Blue!");
+ return this;
}
});
Something went wrong with that request. Please try again.