model tree struct draft

This commit is contained in:
Ludovic Stephan 2017-03-15 02:45:13 -03:00
parent 02485afd9b
commit 0219d998ac

View file

@ -572,75 +572,74 @@ class Article extends ModelObject {
set price(v) { this._price = floatCheck(v); } set price(v) { this._price = floatCheck(v); }
} }
class TreeNode {
constructor(type, content) {
this.type = type;
this.content = content;
this.parent = null;
this.children = [];
}
}
/** /**
* Simple {@link Models.ModelObject} list. * Simple {@link Models.ModelObject} list.
* @memberof Models * @memberof Models
*/ */
class ModelList { class ModelTree {
/** /**
* Nested structure of the list * Nested structure of the list
* @abstract * @abstract
* @type {Models.ModelObject[]} * @type {Models.ModelObject[]}
*/ */
static get models() { return []; } static get models() { return {}; }
/**
* Verbose names for list models
* @abstract
* @type {string[]}
*/
static get names() {
return this.models.map(function(v) {
return v.verbose_name;
});
}
/** /**
* Creates empty instance and populates it with data if given * Creates empty instance and populates it with data if given
* @param {Object[]} [datalist=[]] * @param {Object[]} [datalist=[]]
*/ */
constructor(datalist) { constructor(datalist) {
this.data = {}; this._root = new TreeNode({}) ;
this.from(datalist || []); this.from(datalist || []);
} }
/** /**
* Fetches an object from the instance data, or creates it if * Fetches an object from the instance data, or creates it if
* it does not exist yet.<br> * it does not exist yet.<br>
* Parent objects are created recursively if needed. * If direction >= 0, parent objects are created recursively.
* If direction <= 0, child objects are created recursively.
* @param {number} depth depth on the nested structure of the list * @param {number} depth depth on the nested structure of the list
* @param {Object} data * @param {Object} data
*/ */
get_or_create(depth, data) { get_or_create(data, direction=0) {
var model = this.constructor.models[depth]; var model = this.constructor.models[data.type];
var name = model.verbose_name ;
var existing = this.data[name].find(function (v){
return v.id === data['id'] ;
}) ;
var existing = this.find(data.type, data.content.id);
if (existing) { if (existing) {
return existing; return existing;
} }
if (depth == this.constructor.models.length-1) { var content = new this.constructor.models[data.type]();
var created = new model(data) ; var node = new TreeNode(data.type, content);
this.data[name].push(created);
return created ;
} else {
var par_name = this.constructor.models[depth+1]
.verbose_name;
var par_data = data[par_name]; if (direction <= 0) {
var created = new model(data); var parent = data.parent ? this.get_or_create(data.parent, -1) : this._root;
var parnt = this.get_or_create(depth+1, par_data); node.parent = parent;
created[par_name] = parnt; parent.children.push(node);
this.data[name].push(created);
return created ;
} }
if (direction >= 0) {
for (let child_data of data.children) {
var child = this.get_or_create(child_data, 1);
child.parent = node;
node.children.push(child);
}
}
return node ;
} }
/** /**
@ -655,7 +654,7 @@ class ModelList {
} }
for (let data of datalist) { for (let data of datalist) {
this.get_or_create(0, data); this.get_or_create(data, 0);
} }
} }
@ -728,18 +727,19 @@ class ModelList {
* @param {class} model * @param {class} model
* @param {Object} props Properties to match * @param {Object} props Properties to match
*/ */
find(model, props) { find(type, id) {
if (this.constructor.models.indexOf(model) == -1) { (function recurse(node) {
return undefined ; if (node.type === type && node.data.id === id)
} return node ;
return this.data[model.verbose_name].find(function(v) { for (let child of node.children) {
for (let key in props) { var result = recurse(child) ;
if (v[key] !== props[key]) if (result)
return false; return result;
} }
return true;
}); return null;
})(this._root;)
} }
} }