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

[Bugfix] LazyGet of aliasDescriptor should respected the aliased... #5289

Closed
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
19 changes: 19 additions & 0 deletions packages/ember-metal/lib/alias.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,22 @@ function AliasedProperty_oneWaySet(obj, keyName, value) {
// Backwards compatibility with Ember Data
AliasedProperty.prototype._meta = undefined;
AliasedProperty.prototype.meta = ComputedProperty.prototype.meta;

AliasedProperty.prototype.isCacheable = function(meta) {
var desc = meta.descs[this.altKey];
return desc && desc.isCacheable();
};

AliasedProperty.prototype.cacheGet = function(meta, key) {
var desc = meta.descs[this.altKey];
return desc && desc.cacheGet(meta, this.altKey);
};

AliasedProperty.prototype.lazyGet = function(obj, meta, key) {
var desc = meta.descs[this.altKey];
if (this.isCacheable(meta)) {
return desc.lazyGet(obj, meta, this.altKey);
} else {
return this.get(obj, this.altKey);
}
};
8 changes: 2 additions & 6 deletions packages/ember-metal/lib/chains.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,8 @@ function lazyGet(obj, key) {

// if a CP only return cached value
var desc = meta && meta.descs[key];
if (desc && desc._cacheable) {
if (key in meta.cache) {
return meta.cache[key];
} else {
return undefined;
}
if (desc) {
return desc.lazyGet(obj, meta, key);
}

return get(obj, key);
Expand Down
40 changes: 35 additions & 5 deletions packages/ember-metal/lib/computed.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,29 @@ ComputedPropertyPrototype._dependentKeys = undefined;
ComputedPropertyPrototype._suspended = undefined;
ComputedPropertyPrototype._meta = undefined;

/**
ComputedPropertyPrototype.lazyGet = function(obj, meta, key) {
if (this.isCacheable(meta)) {
return this.cacheGet(meta, key);
} else {
return this.get(obj, key);
}
};


ComputedPropertyPrototype.cacheGet = function(meta, key) {
var result = meta.cache[key];
if (result === UNDEFINED) {
return undefined;
} else {
return result;
}
};

ComputedPropertyPrototype.isCacheable = function(meta) {
return this._cacheable;
};

/**
Properties are cacheable by default. Computed property will automatically
cache the return value of your function until one of the dependent keys changes.

Expand Down Expand Up @@ -503,11 +525,19 @@ function computed(func) {
*/
function cacheFor(obj, key) {
var meta = obj['__ember_meta__'];
var cache = meta && meta.cache;
var ret = cache && cache[key];
if (meta) {
var descs = meta.descs;
var desc = descs && descs[key];
if (desc) {
return desc.cacheGet(meta, key);
} else {
var cache = meta.cache;
var ret = cache && cache[key];

if (ret === UNDEFINED) { return undefined; }
return ret;
if (ret === UNDEFINED) { return undefined; }
return ret;
}
}
}

cacheFor.set = function(cache, key, value) {
Expand Down
47 changes: 45 additions & 2 deletions packages/ember-metal/tests/alias_test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { alias } from "ember-metal/alias";
import { Descriptor, defineProperty } from "ember-metal/properties";
import {
Descriptor,
defineProperty
} from "ember-metal/properties";
import { get } from 'ember-metal/property_get';
import { set } from 'ember-metal/property_set';
import { meta } from 'ember-metal/utils';
import { isWatching } from "ember-metal/watching";
import { addObserver, removeObserver } from "ember-metal/observer";
import {
addObserver,
removeObserver
} from "ember-metal/observer";
import { mixin, observer } from 'ember-metal/mixin';
import { computed } from 'ember-metal/computed';

var obj, count;

Expand Down Expand Up @@ -58,3 +65,39 @@ test('immediately sets up dependencies if already being watched', function() {
set(obj, 'foo.faz', 'BAR');
equal(count, 1);
});

test("Ember.cacheFor simple", function() {
defineProperty(obj, 'baz', computed(function() {
return 'quz';
}));
defineProperty(obj, 'bar', alias('baz'));
equal(Ember.cacheFor(obj, 'bar'), undefined);
Ember.get(obj, 'bar');
deepEqual(Ember.cacheFor(obj, 'bar'), 'quz');
});

test("Ember.cacheFor nonCP", function() {
defineProperty(obj, 'bar', alias('foo'));
equal(Ember.cacheFor(obj, 'bar'), undefined);
Ember.get(obj, 'bar');
equal(Ember.cacheFor(obj, 'bar'), undefined);
});

test("Ember.cacheFor non path CP", function() {
defineProperty(obj, 'bar', alias('foo.faz'));
equal(Ember.cacheFor(obj, 'bar'), undefined);
Ember.get(obj, 'bar');
equal(Ember.cacheFor(obj, 'bar'), undefined);
});


test("Ember.cacheFor path CP", function() {
obj.bro = { };
defineProperty(obj.bro, 'bar', computed(function() {
return 'hombre';
}));
defineProperty(obj, 'bar', alias('bro.bar'));
equal(Ember.cacheFor(obj, 'bar'), undefined);
equal(Ember.get(obj, 'bar'), 'hombre');
equal(Ember.cacheFor(obj, 'bar'), 'hombre');
});
22 changes: 19 additions & 3 deletions packages/ember-metal/tests/observer_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
} from "ember-metal/property_events";
import { get } from 'ember-metal/property_get';
import { set } from 'ember-metal/property_set';

import { alias } from 'ember-metal/alias';
// ..........................................................
// ADD OBSERVER
//
Expand Down Expand Up @@ -904,10 +904,9 @@ QUnit.module('addObserver - dependentkey with chained properties', {
}
});


testBoth('depending on a chain with a computed property', function (get, set){
defineProperty(obj, 'computed', computed(function () {
return {foo: 'bar'};
return { foo: 'bar' };
}));

var changed = 0;
Expand All @@ -922,6 +921,23 @@ testBoth('depending on a chain with a computed property', function (get, set){
equal(changed, 1, 'should fire observer');
});

testBoth('depending on a chain with Alias property of a cp does not computed the CP', function (get, set){
defineProperty(obj, 'computed', computed(function () {
return { foo: 'bar' };
}));

defineProperty(obj, 'alias', alias('computed'));

var changed = 0;
addObserver(obj, 'alias.foo', function () {
changed++;
});

equal(undefined, cacheFor(obj, 'alias'), 'addObserver should not compute CP');

set(obj, 'computed.foo', 'baz');
});

testBoth('depending on a simple chain', function(get, set) {

var val ;
Expand Down