Skip to content
Closed
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
15 changes: 10 additions & 5 deletions packages/ember-metal/lib/chains.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ function firstKey(path) {
return path.match(FIRST_KEY)[0];
}

function isObject(obj) {
return obj && (typeof obj === 'object');
function isWatchable(obj) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe export this, so you can use it below in key-stream?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did until async dependency undefineds made me want to cry to the point of sneaking this in. I can take a stab at it again when I emotionally recover.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, understood, makes sense. This is fine then...

if (!obj) {
return;
}

let type = typeof obj;
return type === 'object' || type === 'function';
}

function isVolatile(obj) {
return !(isObject(obj) && obj.isDescriptor && obj._cacheable);
return !(isWatchable(obj) && obj.isDescriptor && obj._cacheable);
}

function Chains() { }
Expand All @@ -42,7 +47,7 @@ export function flushPendingChains() {
}

function addChainWatcher(obj, keyName, node) {
if (!isObject(obj)) {
if (!isWatchable(obj)) {
return;
}

Expand All @@ -63,7 +68,7 @@ function addChainWatcher(obj, keyName, node) {
}

function removeChainWatcher(obj, keyName, node) {
if (!isObject(obj)) {
if (!isWatchable(obj)) {
return;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/ember-metal/lib/streams/key-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ merge(KeyStream.prototype, {
if (object !== this.observedObject) {
this._clearObservedObject();

if (object && typeof object === 'object') {
var type = typeof object;
if (object && (type === 'object' || type === 'function')) {
addObserver(object, this.key, this, this.notify);
this.observedObject = object;
}
Expand Down
17 changes: 17 additions & 0 deletions packages/ember-metal/tests/streams/key-stream-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ QUnit.test('is notified when the observed object\'s property is mutated', functi
equal(nameStream.value(), 'wycats', 'Stream value is correct');
});

QUnit.test('is notified when properties on functions are mutated', function() {
var fn = function() {};
fn.foo = 'mmun';
source = new Stream(function() { return fn; });

var nameStream = source.get('foo');
nameStream.subscribe(incrementCount);

equal(count, 0, 'Subscribers called correct number of times');
equal(nameStream.value(), 'mmun', 'Stream value is correct');

set(fn, 'foo', 'wycats');

equal(count, 1, 'Subscribers called correct number of times');
equal(nameStream.value(), 'wycats', 'Stream value is correct');
});

QUnit.test('is notified when the source stream\'s value changes to a new object', function() {
var nameStream = source.get('name');
nameStream.subscribe(incrementCount);
Expand Down
19 changes: 19 additions & 0 deletions packages/ember-metal/tests/watching/watch_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,22 @@ testBoth('watching "length" property on an array', function(get, set) {
equal(get(arr, 'length'), 10, 'should get new value');
equal(arr.length, 10, 'property should be accessible on arr');
});

testBoth('watching properties on a function', function(get, set) {
var obj = {
foo: function() {}
};
addListeners(obj, 'foo.baz');

watch(obj, 'foo.baz');
equal(get(obj, 'foo.baz'), undefined, 'should have original prop');

set(obj, 'foo.baz', 'bar');
equal(willCount, 1, 'should have invoked willCount');
equal(didCount, 1, 'should have invoked didCount');

equal(get(obj, 'foo.baz'), 'bar', 'should get new value');
equal(obj.foo.baz, 'bar', 'property should be accessible on obj');
});