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

[PERF beta] @each should remain a stable node for chains. #11984

Merged
merged 1 commit into from
Aug 6, 2015
Merged
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
17 changes: 1 addition & 16 deletions packages/ember-metal/lib/chains.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,6 @@ function ChainNode(parent, key, value) {
addChainWatcher(this._object, this._key, this);
}
}

// Special-case: the EachProxy relies on immediate evaluation to
// establish its observers.
//
// TODO: Replace this with an efficient callback that the EachProxy
// can implement.
if (this._parent && this._parent._key === '@each') {
this.value();
}
}

function lazyGet(obj, key) {
Expand All @@ -216,7 +207,7 @@ function lazyGet(obj, key) {
}

// Use `get` if the return value is an EachProxy or an uncacheable value.
if (key === '@each' || isVolatile(obj[key])) {
if (isVolatile(obj[key])) {
return get(obj, key);
// Otherwise attempt to get the cached value of the computed property
} else {
Expand Down Expand Up @@ -374,12 +365,6 @@ ChainNode.prototype = {
addChainWatcher(obj, this._key, this);
}
this._value = undefined;

// Special-case: the EachProxy relies on immediate evaluation to
// establish its observers.
if (this._parent && this._parent._key === '@each') {
this.value();
}
}

// then notify chains...
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-metal/lib/expand_properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var SPLIT_REGEX = /\{|\}/;
Ember.expandProperties('{foo,bar}', echo); //=> 'foo', 'bar'
Ember.expandProperties('foo.{bar,baz}', echo); //=> 'foo.bar', 'foo.baz'
Ember.expandProperties('{foo,bar}.baz', echo); //=> 'foo.baz', 'bar.baz'
Ember.expandProperties('foo.{bar,baz}.@each', echo) //=> 'foo.bar.@each', 'foo.baz.@each'
Ember.expandProperties('foo.{bar,baz}.[]', echo) //=> 'foo.bar.[]', 'foo.baz.[]'
Ember.expandProperties('{foo,bar}.{spam,eggs}', echo) //=> 'foo.spam', 'foo.eggs', 'bar.spam', 'bar.eggs'
Ember.expandProperties('{foo}.bar.{baz}') //=> 'foo.bar.baz'
```
Expand Down
5 changes: 3 additions & 2 deletions packages/ember-metal/tests/expand_properties_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ QUnit.test('Properties without expansions are unaffected', function() {

expandProperties('a', addProperty);
expandProperties('a.b', addProperty);
expandProperties('a.b.@each', addProperty);
expandProperties('a.b.[]', addProperty);
expandProperties('[email protected]', addProperty);

deepEqual(['a', 'a.b', 'a.b.@each'].sort(), foundProperties.sort());
deepEqual(['a', 'a.b', 'a.b.[]', 'a.b.@each.c'].sort(), foundProperties.sort());
});

QUnit.test('A single expansion at the end expands properly', function() {
Expand Down
27 changes: 12 additions & 15 deletions packages/ember-runtime/lib/mixins/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
sendEvent,
hasListeners
} from 'ember-metal/events';
import { isWatching } from 'ember-metal/watching';
import EachProxy from 'ember-runtime/system/each_proxy';

function arrayObserversHelper(obj, target, opts, operation, notify) {
var willChange = (opts && opts.willChange) || 'arrayWillChange';
Expand Down Expand Up @@ -422,13 +422,13 @@ export default Mixin.create(Enumerable, {
}
}

// Make sure the @each proxy is set up if anyone is observing @each
if (isWatching(this, '@each')) {
get(this, '@each');
if (this.__each) {
this.__each.arrayWillChange(this, startIdx, removeAmt, addAmt);
}

sendEvent(this, '@array:before', [this, startIdx, removeAmt, addAmt]);


if (startIdx >= 0 && removeAmt >= 0 && get(this, 'hasEnumerableObservers')) {
removing = [];
lim = startIdx + removeAmt;
Expand Down Expand Up @@ -489,6 +489,11 @@ export default Mixin.create(Enumerable, {
}

this.enumerableContentDidChange(removeAmt, adding);

if (this.__each) {
this.__each.arrayDidChange(this, startIdx, removeAmt, addAmt);
}

sendEvent(this, '@array:change', [this, startIdx, removeAmt, addAmt]);

var length = get(this, 'length');
Expand All @@ -508,10 +513,6 @@ export default Mixin.create(Enumerable, {
return this;
},

// ..........................................................
// ENUMERATED PROPERTIES
//

/**
Returns a special object that can be used to observe individual properties
on the array. Just get an equivalent property on this object and it will
Expand All @@ -525,15 +526,11 @@ export default Mixin.create(Enumerable, {
@public
*/
'@each': computed(function() {
// TODO use Symbol or add to meta
if (!this.__each) {
// ES6TODO: GRRRRR
var EachProxy = requireModule('ember-runtime/system/each_proxy')['EachProxy'];

this.__each = new EachProxy({
content: this
});
this.__each = new EachProxy(this);
}

return this.__each;
})
}).volatile()
});
Loading