ui: Adds 2 computed utilities, a factory and a purify (#5079)

1. The factory is taken from the ember source, but makes it more
reusable
2. Purify converts conventional ember `computed` into a pure version

This commit only adds new files that could be used further down the line
This commit is contained in:
John Cowen 2019-01-25 12:27:42 +00:00 committed by John Cowen
parent c71f718bc7
commit 4d183ef743
2 changed files with 60 additions and 0 deletions

View File

@ -0,0 +1,18 @@
/**
* Gives you factory function to create a specified type of ComputedProperty
* Largely taken from https://github.com/emberjs/ember.js/blob/v2.18.2/packages/ember-metal/lib/computed.js#L529
* but configurable from the outside (IoC) so its reuseable
*
* @param {Class} ComputedProperty - ComputedProperty to use for the factory
* @returns {function} - Ember-like `computed` function (see https://www.emberjs.com/api/ember/2.18/classes/ComputedProperty)
*/
export default function(ComputedProperty) {
return function() {
const args = [...arguments];
const cp = new ComputedProperty(args.pop());
if (args.length > 0) {
cp.property(...args);
}
return cp;
};
}

View File

@ -0,0 +1,42 @@
import { get } from '@ember/object';
/**
* Converts a conventional non-pure Ember `computed` function into a pure one
* (see https://github.com/emberjs/rfcs/blob/be351b059f08ac0fe709bc7697860d5064717a7f/text/0000-tracked-properties.md#avoiding-dependency-hell)
*
* @param {function} computed - a computed function to 'purify' (convert to a pure function)
* @param {function} filter - Optional string filter function to pre-process the names of computed properties
* @returns {function} - A pure `computed` function
*/
export default function(computed, filter) {
return function() {
let args = [...arguments];
let success = function(value) {
return value;
};
// pop the user function off the end
if (typeof args[args.length - 1] === 'function') {
success = args.pop();
}
if (typeof filter === 'function') {
args = filter(args);
}
// this is the 'conventional' `computed`
const cb = function(name) {
return success.apply(
this,
args.map(item => {
// Right now this just takes the first part of the path so:
// `items.[]` or `items.@each.prop` etc
// gives you `items` which is 'probably' what you expect
// it won't work with something like `item.objects.[]`
// it could potentially be made to do so, but we don't need that right now at least
return get(this, item.split('.')[0]);
})
);
};
// concat/push the user function back on
return computed(...args.concat([cb]));
};
}