Skip to content
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

More flexible event binding #87

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions agility.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,33 @@
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 "<eventType>.<namespace>" can be unbound with an
// unbind call to ".<namespace>" 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);
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);
Expand Down Expand Up @@ -772,6 +799,10 @@
this._events.bind.apply(this, arguments);
return this; // for chainable calls
},
bindFrom: function(){
this._events.bindFrom.apply(this, arguments);
return this;
},
trigger: function(){
this._events.trigger.apply(this, arguments);
return this; // for chainable calls
Expand Down
30 changes: 30 additions & 0 deletions docs/_docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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._
Expand Down
26 changes: 26 additions & 0 deletions docs/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,32 @@ <h3><a href="#core-bind">.bind()</a></h3>
<li><code>event</code>: String specifying event type. See <a href="#events">events</a> section for event syntax.</li>
<li><code>fn</code>: function to be called upon event triggering.</li>
</ul>
<p><strong>Returns:</strong></p>
<p>Owner Agility object (for chainable calls).</p>
<h3><a href="#core-bindfrom">.bindFrom()</a></h3>
<p><em>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.</em></p>
<p><strong>Syntax:</strong></p>
<div class="codehilite"><pre><span class="p">.</span><span class="nx">bindFrom</span><span class="p">(</span><span class="nx">originObject</span><span class="p">,</span> <span class="nx">event</span><span class="p">,</span> <span class="nx">fn</span><span class="p">)</span>
</pre></div>


<ul>
<li><code>originObject</code>: Origin object that causes the event to be unbound when it is destroyed.</li>
<li><code>event</code>: String specifying event type. Only Agility events are supported.</li>
<li><code>fn</code>: function to be called upon event triggering.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="codehilite"><pre><span class="kd">var</span> <span class="nx">model</span> <span class="o">=</span> <span class="nx">$$</span><span class="p">({</span><span class="nx">key</span><span class="o">:</span> <span class="s1">&#39;value&#39;</span><span class="p">});</span>
<span class="kd">var</span> <span class="nx">observer</span> <span class="o">=</span> <span class="nx">$$</span><span class="p">();</span>
<span class="nx">model</span><span class="p">.</span><span class="nx">bindFrom</span><span class="p">(</span><span class="nx">observer</span><span class="p">,</span> <span class="s1">&#39;change&#39;</span><span class="p">,</span> <span class="nx">someHandler</span><span class="p">);</span>
<span class="c1">// someHandler will now be called on model changes</span>
<span class="nx">observer</span><span class="p">.</span><span class="nx">destroy</span><span class="p">();</span>
<span class="c1">// someHandler is now automatically unbound</span>
</pre></div>


<p><strong>Returns:</strong></p>
<p>Owner Agility object (for chainable calls).</p>
<h3><a href="#core-trigger">.trigger()</a></h3>
Expand Down
30 changes: 30 additions & 0 deletions test/public/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,36 @@
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._events.unbind('testevent');
o.trigger('testevent');
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 = $$({}, {}, {
Expand Down