Skip to content

Commit

Permalink
add hotfix for composing class computed
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelly Selden committed May 5, 2018
1 parent bae0225 commit ad72b97
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 8 deletions.
24 changes: 20 additions & 4 deletions addon/create-class-computed.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,27 @@ export default function(observerBools, macroGenerator) {
}

let mappedKeys = [];
let originalKeys = [];

function rewriteComputed(obj, key) {
let mappedWithResolvedOberverKeys = mappedKeys.map((macro, i) => {
function createComputed(keys, context, key) {
let resolvedOberverKeys = keys.map((macro, i) => {
let shouldObserve = observerBools[i];
if (shouldObserve) {
macro = getValue({ context: this, macro, key });
// succeeds with `raw`, fails with everything else
try {
macro = getValue({ context, macro, key });
} catch (err) {
macro = undefined;
}
}
return macro;
});

let cp = macroGenerator.apply(this, mappedWithResolvedOberverKeys);
return macroGenerator.apply(context, resolvedOberverKeys);
}

function rewriteComputed(obj, key) {
let cp = createComputed(mappedKeys, this, key);
defineProperty(this, 'computed', cp);
}

Expand All @@ -124,6 +134,7 @@ export default function(observerBools, macroGenerator) {

let mappedKey = resolveMappedLocation(key, i);

originalKeys.push(key);
mappedKeys.push(mappedKey);
if (shouldObserve) {
classProperties[`key${i}DidChange`] = observer(mappedKey, rewriteComputed);
Expand Down Expand Up @@ -159,6 +170,11 @@ export default function(observerBools, macroGenerator) {
return get(propertyInstance, 'computed');
}).readOnly();

// workaround for watching array and object rewriting properties
// in class computed scope while composing macros
// ex `first(filterBy('arr', 'prop'))`
cp._classComputed = createComputed(originalKeys);

return cp;
};
}
8 changes: 8 additions & 0 deletions addon/flatten-keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ function flattenKey(key, flattenedKeys) {
return;
}

// workaround for watching array and object rewriting properties
// in class computed scope while composing macros
// ex `first(filterBy('arr', 'prop'))`
let classComputed = key._classComputed;
if (classComputed) {
dependentKeys = classComputed._dependentKeys;
}

return _flattenKeys(dependentKeys, flattenedKeys);
}

Expand Down
10 changes: 10 additions & 0 deletions tests/acceptance/application-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,14 @@ module('Acceptance | application', function(hooks) {

assert.equal(find('.items').textContent, 1);
});

test('class computed array macro inside a normal array macro, handles pushes', async function(assert) {
await visit('/compose-class-computed');

assert.equal(find('.computed').textContent, '1');

await click('button');

assert.equal(find('.computed').textContent, '3');
});
});
41 changes: 41 additions & 0 deletions tests/dummy/app/controllers/compose-class-computed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Controller from '@ember/controller';
import EmberObject, { get } from '@ember/object';
import { A as emberA } from '@ember/array';
import createClassComputed from 'ember-macro-helpers/create-class-computed';
import computed from 'ember-macro-helpers/computed';
import raw from 'ember-macro-helpers/raw';
import normalizeArrayKey from 'ember-macro-helpers/normalize-array-key';

const filterBy = createClassComputed(
[false, true],
(arr, key, val) => computed(normalizeArrayKey(arr, [key]), val, (arr, val) => arr.filterBy(key, val))
);

export default Controller.extend({
array: emberA([
EmberObject.create({
testProp: 'test val 1',
testProp2: 1
}),
EmberObject.create({
testProp: 'test val 2',
testProp2: 2
})
]),
index: 0,
testProp: 'testProp',

computed: computed(
filterBy('array', 'testProp', raw('test val 1')),
array => get(array[array.length - 1], 'testProp2')
),

actions: {
update() {
get(this, 'array').pushObject(EmberObject.create({
testProp: 'test val 1',
testProp2: 3
}));
}
}
});
1 change: 1 addition & 0 deletions tests/dummy/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const Router = EmberRouter.extend({
Router.map(function() {
this.route('double-render');
this.route('no-rerender');
this.route('compose-class-computed');
});

export default Router;
3 changes: 3 additions & 0 deletions tests/dummy/app/templates/compose-class-computed.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="computed">{{computed}}</div>

<button {{action "update"}}></button>
2 changes: 1 addition & 1 deletion tests/integration/create-class-computed-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module('Integration | create class computed', function(hooks) {
filterBy = createClassComputed(
[false, true],
function(array, key, value) {
if (!key) {
if (!key && this) {
PROPERTIES.set(this, array.split('.').reverse()[0]);
}
return computed(normalizeArrayKey(array, [key]), value, function(array, value) {
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/create-class-computed-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,13 @@ module('Unit | create class computed', function(hooks) {
}
});

assert.equal(observerCallback.callCount, 2);
assert.equal(observerCallback.callCount, 3);

assert.equal(callback.callCount, 2);

subject.set('test5', 'test6');

assert.equal(observerCallback.callCount, 3);
assert.equal(observerCallback.callCount, 4);

subject.get('computed');

Expand All @@ -156,7 +156,7 @@ module('Unit | create class computed', function(hooks) {

subject.get('computed');

assert.equal(observerCallback.callCount, 3);
assert.equal(observerCallback.callCount, 4);

assert.equal(callback.callCount, 4);
});
Expand Down

0 comments on commit ad72b97

Please sign in to comment.