Skip to content

Commit

Permalink
add DidChangeAttrs mixin
Browse files Browse the repository at this point in the history
  • Loading branch information
GavinJoyce committed Oct 31, 2017
1 parent 6880a1e commit fa56b35
Show file tree
Hide file tree
Showing 4 changed files with 546 additions and 19 deletions.
57 changes: 56 additions & 1 deletion addon/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
/* Hey @GavinJoyce, add your code here! :) */
import WeakMap from 'ember-weakmap';
import Ember from 'ember';

function isEqual(key, a, b) {
return a === b;
}

export default Ember.Mixin.create({
_didChangeAttrsWeakMap: null, //this tracks previous state of any `trackAttrChanges`
didChangeAttrsConfig: [], //attributes to track

didReceiveAttrs() {
this._super(...arguments);

let weakMap = this.get('_didChangeAttrsWeakMap');

if (weakMap === null) { //first run
let config = this.get('didChangeAttrsConfig');
let trackedAttrs = config.attrs;
let initialValues = {};

for (let i=0; i<trackedAttrs.length; i++) {
let key = trackedAttrs[i];
initialValues[key] = this.get(key);
}

weakMap = new WeakMap();
weakMap.set(this, initialValues);
this.set('_didChangeAttrsWeakMap', weakMap);
}
},

didUpdateAttrs() {
this._super(...arguments);

let config = this.get('didChangeAttrsConfig');
let trackedAttrs = config.attrs;
let oldValues = this.get('_didChangeAttrsWeakMap').get(this);
let changes = {};

for (let i=0; i<trackedAttrs.length; i++) {
let key = trackedAttrs[i];
let current = this.get(key);
let previous = oldValues[key];

if (!isEqual(key, previous, current)) { //TODO: configurable equality fn
changes[key] = { previous, current };
oldValues[key] = current;
}
}

if(Object.keys(changes).length > 0) {
this.didChangeAttrs(changes);
}
},
});
Empty file removed tests/integration/.gitkeep
Empty file.
49 changes: 49 additions & 0 deletions tests/integration/did-change-attrs-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Ember from 'ember';
import { test, moduleForComponent } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import DidChangeAttrs from 'ember-did-change-attrs';

function registerComponent(testSuite, hash, klass = Ember.Component) {
testSuite.register('component:x-changer', klass.extend(DidChangeAttrs, hash));
}

moduleForComponent('x-changer', 'Integration | DidChangeAttrs', {
integration: true
});

test('Basic usage', function(assert) {
let changedAttrs, didChangeAttrsCallCount = 0;

registerComponent(this, {
didChangeAttrsConfig: {
attrs: ['email', 'isAdmin']
},

didChangeAttrs(changes) {
this._super(...arguments);

didChangeAttrsCallCount++;
changedAttrs = changes;
}
});

this.set('name', 'Tomster');
this.set('email', '[email protected]');
this.set('isAdmin', false);

this.render(hbs`{{x-changer email=email isAdmin=isAdmin name=name}}`);
assert.equal(didChangeAttrsCallCount, 0, '`didChangeAttrs` is not called on initial render');

this.set('email', '[email protected]');
assert.equal(didChangeAttrsCallCount, 1, '`didChangeAttrs` is called when an attribute changed');

assert.deepEqual(changedAttrs, {
email: {
previous: '[email protected]',
current: '[email protected]'
}
}, '`changedAttrs` contains the attribute changes');

this.set('name', 'TheTomster');
assert.equal(didChangeAttrsCallCount, 1, '`didChangeAttrs` is not called when an untracked attribute is changed');
});
Loading

0 comments on commit fa56b35

Please sign in to comment.