File: addon/hierarchy/hasManyWithHierarchy.js
import Ember from 'ember';
function getObjForHierarchyLevel(obj, meta, hierarchy, level) {
var param = {};
param[hierarchy[level].childrenKey] = Ember.typeOf(obj) === "array" ? obj : Ember.A([obj]);
return hierarchy[level].classes[hierarchy[level].base].create(param);
}
function getObjTillLevel(obj, meta, hierarchy, fromLevel, toLevel) {
for(var i = fromLevel - 1; i >= toLevel; i--) {
obj = getObjForHierarchyLevel(obj, meta, hierarchy, i);
}
return obj;
}
/**
* Creates a computed property which creates a class for every element in the set array based on hierarchy.
* The objects in the array can be of any level at or below the current level. An instance with the basic class is automatically wrapped around the objects at lower level.
*
* @method hasManyWithHierarchy
* @static
* @param {Object} hasManyHierarchy Assumed to be already initialized by calling 'registerHierarchy'.
* @param {Number} level Level of the computed property.
* @param {String} key Key used to get the key used in retrieving the class object in the classes map.
* @returns {Instance}
*/
export default function hasManyWithHierarchy(hasManyHierarchy, level, hkey) {
var meta;
if(Ember.typeOf(hasManyHierarchy) === "array") {
meta = hasManyHierarchy.hierarchyMeta;
}
return Ember.computed(function(key, newval) {
if(arguments.length > 1) {
if(Ember.typeOf(hasManyHierarchy) === "string") {
hasManyHierarchy = Ember.get(hasManyHierarchy);
meta = hasManyHierarchy.hierarchyMeta;
}
if(newval) {
//curLevel, curLevelArray
var cl = -1, cla = Ember.A([]);
for(var i = 0; i < newval.length; i++) {
var obj = newval[i], _obj = {},
type = Ember.typeOf(obj) === "array" ? obj[0] : obj[hkey],
objMeta = meta[type];
if(Ember.typeOf(obj) !== "instance") {
if(objMeta && objMeta.level >= level) {
if(Ember.typeOf(obj) === "array") {
for(var j = 0; j < hasManyHierarchy[objMeta.level].keysInArray.length; j++) {
if(j < obj.length) {
_obj[hasManyHierarchy[objMeta.level].keysInArray[j]] = obj[j];
}
}
}
else {
_obj = obj;
}
_obj = hasManyHierarchy[objMeta.level].classes[type].create(_obj);
if(cl === -1 || cl === objMeta.level) {
cla.push(_obj);
cl = objMeta.level;
}
else if(cl < objMeta.level) {
cla.push(getObjTillLevel(_obj, meta, hasManyHierarchy, objMeta.level, cl));
}
else {
var curObj = getObjForHierarchyLevel(cla, meta, hasManyHierarchy, objMeta.level);
cl = objMeta.level;
cla = Ember.A([curObj, _obj]);
}
}
}
else {
cla.push(obj);
}
}
if(cl === level || cl === -1) {
newval = cla;
}
else {
newval = Ember.A([getObjTillLevel(cla, meta, hasManyHierarchy, cl, level)]);
}
}
this["_" + key] = newval;
return newval;
}
else {
return this["_" + key];
}
});
}