Skip to content

Instantly share code, notes, and snippets.

@green3g
Created October 20, 2017 13:36
Show Gist options
  • Save green3g/8a52e5e710280ad6e9d01483d1e695d6 to your computer and use it in GitHub Desktop.
Save green3g/8a52e5e710280ad6e9d01483d1e695d6 to your computer and use it in GitHub Desktop.
Decorate an esri/core/Accessor with canjs observable symbols
import canSymbol from 'can-symbol';
import observation from 'can-observation';
import get from 'can-util/js/get/get';
/**
* Decorate esri's observable type with canjs methods
* @param {esri/core/Accessor} obj the current object being accessed
* @param {esri/core/Accessor} parent the root parent accessor object
* @param {String} path the path to the value of the object from the parent
* @returns {esri/core/Accessor} the decorated object or the value if `obj` is not an object
*/
export default function decorate (obj, parent = null, path = null) {
// make sure object exists and isn't already decorated through circular references
if (!obj || !obj.__accessor__ || obj[canSymbol.for('can.onKeyValue')]) {
return obj;
}
const handlers = {
};
obj[canSymbol.for('can.isMapLike')] = true;
obj[canSymbol.for('can.offKeyValue')] = function (key, handler) {
if (!handlers[key]) {
handlers[key] = [];
}
const filtered = handlers[key].filter((handle) => {
return handle.handle === handler;
})[0];
if (filtered) {
filtered.watch.remove();
handlers[key].splice(obj.handlers[key].indexOf(handler), 1);
}
};
obj[canSymbol.for('can.onKeyValue')] = function (key, handler) {
console.log(key, handler);
const watchProp = path ? `${path}.${key}` : key;
const watch = (parent || obj).watch(watchProp, (newValue, oldValue, propertyName, target) => {
handlers[key].forEach((handle) => {
handle.handle.call(obj, newValue, oldValue);
});
});
if (!handlers[key]) {
handlers[key] = [];
}
handlers[key].push({handle: handler, watch: watch});
};
obj[canSymbol.for('can.getKeyValue')] = function (key) {
const fullPath = path ? `${path}.${key}` : key;
observation.add(obj, key);
console.log(obj, key);
return get(parent || obj, fullPath);
};
// decorate child keys
obj.keys().forEach((key) => {
const fullPath = path ? `${path}.${key}` : key;
console.log(key);
decorate(obj[key], (parent || obj), fullPath);
});
return obj;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment