From 68351db364b99ffb1485f9d22a691941c2cf3e33 Mon Sep 17 00:00:00 2001 From: Pindi Albert Date: Tue, 12 Jun 2012 14:00:28 -0700 Subject: [PATCH 1/3] Implement unbind to remove an event binding --- agility.js | 14 ++++++++++++++ test/public/core.js | 15 +++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/agility.js b/agility.js index e9a9566..7ea51ae 100644 --- a/agility.js +++ b/agility.js @@ -291,6 +291,16 @@ return this; // for chainable calls }, // bind + unbind: function(eventStr){ + // Only works with custom events for now + var eventObj = this._events.parseEventStr(eventStr); + if(eventObj.selector){ + throw "Unbind does not yet work with jQuery events"; + } else { + $(this._events.data).unbind(eventObj.type); + } + }, // unbind + // Triggers eventStr. Syntax for eventStr is same as that for bind() trigger: function(eventStr, params){ var eventObj = this._events.parseEventStr(eventStr); @@ -772,6 +782,10 @@ this._events.bind.apply(this, arguments); return this; // for chainable calls }, + unbind: function(){ + this._events.unbind.apply(this, arguments); + return this; // for chainable calls + }, trigger: function(){ this._events.trigger.apply(this, arguments); return this; // for chainable calls diff --git a/test/public/core.js b/test/public/core.js index 55b0f0b..044ab92 100644 --- a/test/public/core.js +++ b/test/public/core.js @@ -1072,6 +1072,21 @@ ok(parent2Called, "event bubbled to parent 2"); }); + + test("Unbinding events", function(){ + var eventCalled = false; + var o = $$(); + o.bind('testevent', function(){ + eventCalled = true; + }); + o.trigger('testevent'); + ok(eventCalled, "event handler called after bind"); + eventCalled = false; + o.unbind('testevent'); + o.trigger('testevent'); + ok(!eventCalled, "event handler not called after unbind"); + }); + test("Model events", function(){ var t = false; var obj = $$({}, {}, { From 7b694e192fd9bd3669f023b7e4131d04c8410d79 Mon Sep 17 00:00:00 2001 From: Pindi Albert Date: Tue, 3 Jul 2012 17:48:04 -0700 Subject: [PATCH 2/3] Implement bindFrom, which automatically unbinds an event when the "origin object" is destroyed --- agility.js | 21 +++++++++++++++++++++ test/public/core.js | 15 +++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/agility.js b/agility.js index 7ea51ae..a42c12b 100644 --- a/agility.js +++ b/agility.js @@ -291,6 +291,23 @@ return this; // for chainable calls }, // bind + // Binds eventStr to fn from originObject. When originObject is destroyed, + // the event is automatically unbound. + bindFrom: function(originObject, eventStr, fn){ + var eventObj = this._events.parseEventStr(eventStr); + if(eventObj.selector){ + throw "bindFrom does not yet work with jQuery events"; + } else { + // jQuery namespaced events: events of the form "." can be unbound with an + // unbind call to "." without affecting other events. + this._events.bind(eventObj.type + '.' + originObject._id.toString(), fn); + var self = this; + originObject.bind('_destroy', function(){ + self._events.unbind('.' + originObject._id.toString()); + }); + } + }, // bindFrom + unbind: function(eventStr){ // Only works with custom events for now var eventObj = this._events.parseEventStr(eventStr); @@ -782,6 +799,10 @@ this._events.bind.apply(this, arguments); return this; // for chainable calls }, + bindFrom: function(){ + this._events.bindFrom.apply(this, arguments); + return this; + }, unbind: function(){ this._events.unbind.apply(this, arguments); return this; // for chainable calls diff --git a/test/public/core.js b/test/public/core.js index 044ab92..a170c56 100644 --- a/test/public/core.js +++ b/test/public/core.js @@ -1087,6 +1087,21 @@ ok(!eventCalled, "event handler not called after unbind"); }); + test("Binding events with bindFrom", function(){ + var eventCalled = false; + var origin = $$(); + var o = $$(); + o.bindFrom(origin, 'testevent', function(){ + eventCalled = true; + }); + o.trigger('testevent'); + ok(eventCalled, "event handler called after bind"); + eventCalled = false; + origin.destroy(); + o.trigger('testevent'); + ok(!eventCalled, "event handler not called after origin destoyed"); + }); + test("Model events", function(){ var t = false; var obj = $$({}, {}, { From 61429a8743e0a285f11031fe069aa71a15234151 Mon Sep 17 00:00:00 2001 From: Pindi Albert Date: Tue, 3 Jul 2012 18:46:32 -0700 Subject: [PATCH 3/3] Document bindFrom, change unbind to private --- agility.js | 4 ---- docs/_docs.md | 30 ++++++++++++++++++++++++++++++ docs/docs.html | 26 ++++++++++++++++++++++++++ test/public/core.js | 2 +- 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/agility.js b/agility.js index a42c12b..fd91591 100644 --- a/agility.js +++ b/agility.js @@ -803,10 +803,6 @@ this._events.bindFrom.apply(this, arguments); return this; }, - unbind: function(){ - this._events.unbind.apply(this, arguments); - return this; // for chainable calls - }, trigger: function(){ this._events.trigger.apply(this, arguments); return this; // for chainable calls diff --git a/docs/_docs.md b/docs/_docs.md index 3486f20..f64199a 100644 --- a/docs/_docs.md +++ b/docs/_docs.md @@ -518,6 +518,36 @@ _Binds function to event._ Owner Agility object (for chainable calls). +### [.bindFrom()](#core-bindfrom) + +_Binds a function to event from an "origin object". +When the origin object is destroyed, the event handler is automatically unbound. +Useful for short-lived objects that bind to events in more long-lived objects._ + +**Syntax:** + + :::javascript + .bindFrom(originObject, event, fn) + ++ `originObject`: Origin object that causes the event to be unbound when it is destroyed. ++ `event`: String specifying event type. Only Agility events are supported. ++ `fn`: function to be called upon event triggering. + +**Example:** + + :::javascript + var model = $$({key: 'value'}); + var observer = $$(); + model.bindFrom(observer, 'change', someHandler); + // someHandler will now be called on model changes + observer.destroy(); + // someHandler is now automatically unbound + +**Returns:** + +Owner Agility object (for chainable calls). + + ### [.trigger()](#core-trigger) _Triggers event, optionally passing parameters to listeners._ diff --git a/docs/docs.html b/docs/docs.html index 08db366..7afa697 100644 --- a/docs/docs.html +++ b/docs/docs.html @@ -567,6 +567,32 @@

.bind()

  • event: String specifying event type. See events section for event syntax.
  • fn: function to be called upon event triggering.
  • +

    Returns:

    +

    Owner Agility object (for chainable calls).

    +

    .bindFrom()

    +

    Binds a function to event from an "origin object". +When the origin object is destroyed, the event handler is automatically unbound. +Useful for short-lived objects that bind to events in more long-lived objects.

    +

    Syntax:

    +
    .bindFrom(originObject, event, fn)
    +
    + + +
      +
    • originObject: Origin object that causes the event to be unbound when it is destroyed.
    • +
    • event: String specifying event type. Only Agility events are supported.
    • +
    • fn: function to be called upon event triggering.
    • +
    +

    Example:

    +
    var model = $$({key: 'value'});
    +var observer = $$();
    +model.bindFrom(observer, 'change', someHandler);
    +// someHandler will now be called on model changes
    +observer.destroy();
    +// someHandler is now automatically unbound
    +
    + +

    Returns:

    Owner Agility object (for chainable calls).

    .trigger()

    diff --git a/test/public/core.js b/test/public/core.js index a170c56..b2e50a8 100644 --- a/test/public/core.js +++ b/test/public/core.js @@ -1082,7 +1082,7 @@ o.trigger('testevent'); ok(eventCalled, "event handler called after bind"); eventCalled = false; - o.unbind('testevent'); + o._events.unbind('testevent'); o.trigger('testevent'); ok(!eventCalled, "event handler not called after unbind"); });