Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Allow a one-time event listener on Ember.Evented

This commit allows you to listen for an event
once. Once the event fires, Ember immediately
unbinds it.

The API is modeled after jQuery's .one method.
  • Loading branch information...
commit 1809e65012b93c0a530bfcb95eec22d972069745 1 parent 332d214
Tomhuda Katzdale authored
View
19 packages/ember-runtime/lib/mixins/evented.js
@@ -16,6 +16,25 @@ Ember.Evented = Ember.Mixin.create({
Ember.addListener(this, name, target, method, xform);
},
+ one: function(name, target, method) {
+ if (!method) {
+ method = target;
+ target = null;
+ }
+
+ var wrapped = function() {
+ Ember.removeListener(this, name, target, wrapped);
+
+ // Internally, a `null` target means that the target is
+ // the first parameter to addListener. That means that
+ // the `this` passed into this function is the target
+ // determined by the event system.
+ method.apply(this, arguments);
+ };
+
+ this.on(name, target, wrapped);
+ },
+
trigger: function(name) {
Ember.sendEvent.apply(null, [this, name].concat(a_slice.call(arguments, 1)));
},
View
40 packages/ember-runtime/tests/system/object/events_test.js
@@ -16,6 +16,22 @@ test("a listener can be added to an object", function() {
equal(count, 2, "the event was triggered");
});
+test("a listener can be added and removed automatically the first time it is triggerd", function() {
+ var count = 0;
+ var F = function() { count++; };
+
+ var obj = Ember.Object.create(Ember.Evented);
+
+ obj.one('event!', F);
+ obj.trigger('event!');
+
+ equal(count, 1, "the event was triggered");
+
+ obj.trigger('event!');
+
+ equal(count, 1, "the event was not triggered again");
+});
+
test("triggering an event can have arguments", function() {
var self, args;
@@ -32,6 +48,30 @@ test("triggering an event can have arguments", function() {
equal(self, obj);
});
+test("a listener can be added and removed automatically and have arguments", function() {
+ var self, args, count = 0;
+
+ var obj = Ember.Object.create(Ember.Evented);
+
+ obj.one('event!', function() {
+ args = [].slice.call(arguments);
+ self = this;
+ count++;
+ });
+
+ obj.trigger('event!', "foo", "bar");
+
+ deepEqual(args, [ "foo", "bar" ]);
+ equal(self, obj);
+ equal(count, 1, "the event is triggered once");
+
+ obj.trigger('event!', "baz", "bat");
+
+ deepEqual(args, [ "foo", "bar" ]);
+ equal(count, 1, "the event was not triggered again");
+ equal(self, obj);
+});
+
test("binding an event can specify a different target", function() {
var self, args;

1 comment on commit 1809e65

@josepjaume

Awesome! :D

Please sign in to comment.
Something went wrong with that request. Please try again.