emberjs/ember.js — pull request #5482 by mmpestorich (2014-08-25 02:29:43+00:00)
Title: [FEATURE] conditional-observers-and-listeners

I find myself doing the following a lot:

```js
SomeClass = Ember.Object.extend({

enabled: true,

value: 'foo',

valueDidChange: function() {
if (this.get('enabled')) {
// do something after value changes only when enabled is true
}
}.observes('enabled', 'value')
});
```

That works fine under normal circumstances but what happens when your dealing with a large number of these objects and `value` changes frequently when `enabled` is `false`? The `valueDidChange` observer fires needlessly on all of those objects, basically it adds additional overhead that accomplishes nothing.

If we refactor the code a bit, we can avoid this:

```js
SomeClass = Ember.Object.extend({

enabled: true,

enabledDidChange: function() {
if (this.get('enabled')) {
Ember.addObserver(this, 'value', null, 'valueDidChangeWhenEnabled');
} else {
Ember.removeObserver(this, 'value', null, 'valueDidChangeWhenEnabled');
}
}.observes('enabled'),

value: 'foo',

valueDidChangeWhenEnabled: function() {
// do something after value changes only when enabled is true
}
});
```

Now the `value` observer will only fire when `enabled` is `true` because it only exists when `enabled` is `true`. Basically, we've introduced a conditional observer. There were quite a few places where I found this sort of thing useful. So I came up with this commit that essentially allows one to do the same thing in a bit more declarative way:

```js
SomeClass = Ember.Object.extend({

enabled: true,

value: 'foo',

doSomething: function() {
// do something after value changes only when enabled is true
}.observes('value').when('enabled')
});
```

This commit also allows `when` to work with listeners:

```javascript
Ember.TextField.extend({

selectIsEnabled: true,

select: function() {
// Executes on "focusIn" only when selectIsEnabled is true
this.$().select();
}.on('focusIn').when('selectIsEnabled')
});
```

Thoughts?