Skip to content

Instantly share code, notes, and snippets.

@buschtoens
Last active September 4, 2020 17:56
Show Gist options
  • Save buschtoens/708611e904dd515716080305405d86c9 to your computer and use it in GitHub Desktop.
Save buschtoens/708611e904dd515716080305405d86c9 to your computer and use it in GitHub Desktop.
This mixin can be used dry up the diffing of attrs in Ember Components.
import Ember from 'ember';
const EMPTY_OBJECT = Object.freeze(Object.create(null));
const EMPTY_ARRAY = Object.freeze([]);
/**
* @class DiffAttrsMixin
*/
export default Ember.Mixin.create({
/**
* List of attrs that should be diffed.
*
* @property diffAttrs
* @type {Array[String]}
*/
diffAttrs: EMPTY_ARRAY,
/**
* Cache of old attrs values.
*
* @property _oldAttrs
* @type {Object}
* @private
*/
_oldAttrs: EMPTY_OBJECT,
/**
* Sets the `_oldAttrs` property to an empty object.
*
* @method init
* @private
*/
init() {
this.set('_oldAttrs', Object.create(null));
this._super(...arguments);
},
/**
* Calls `_diffAttrs`.
*
* @method didReceiveAttrs
* @private
*/
didReceiveAttrs() {
this._super(...arguments);
this._diffAttrs();
},
/**
* Called for each attribute that has changed. You may override this method.
*
* @method didChangeAttr
* @param {String} name
* @param newValue
* @param oldValue
*/
didChangeAttr(/* name, newValue, oldValue */) {
},
/**
* Checks, if the attrs listed in `diffAttrs` changed and calls
* `didChangeAttr` for each changed attr.
*
* @method _diffAttrs
* @private
*/
_diffAttrs() {
const attrNames = this.get('diffAttrs');
const oldAttrs = this.get('_oldAttrs');
const newAttrs = this.getProperties(attrNames);
attrNames.forEach((name) => {
const oldValue = oldAttrs[name];
const newValue = newAttrs[name];
if (oldValue !== newValue) {
this.didChangeAttr(name, newValue, oldValue);
}
oldAttrs[name] = newAttrs[name];
});
}
});
import Ember from 'ember';
import DiffAttrsMixin from '../mixins/diff-attrs';
export default Ember.Component.extend(DiffAttrsMixin, {
diffAttrs: [
'foo',
'bar'
],
foo: null,
bar: null,
didChangeAttr(name, newValue, oldValue) {
switch (name) {
case 'foo':
console.log(`foo changed from ${oldValue} to ${newValue}`);
break;
case 'bar':
console.log(`bar changed from ${oldValue} to ${newValue}`);
break;
default:
console.log(name, newValue, oldValue);
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment