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); }
}
class TreeNode {
constructor(type, content) {
this.type = type;
this.content = content;
this.parent = null;
this.children = [];
}
}
/**
* Simple {@link Models.ModelObject} list.
* @memberof Models
*/
class ModelList {
class ModelTree {
/**
* Nested structure of the list
* @abstract
* @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
* @param {Object[]} [datalist=[]]
*/
constructor(datalist) {
this.data = {};
this._root = new TreeNode({}) ;
this.from(datalist || []);
}
/**
* Fetches an object from the instance data, or creates it if
* 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 {Object} data
*/
get_or_create(depth, data) {
var model = this.constructor.models[depth];
var name = model.verbose_name ;
var existing = this.data[name].find(function (v){
return v.id === data['id'] ;
}) ;
get_or_create(data, direction=0) {
var model = this.constructor.models[data.type];
var existing = this.find(data.type, data.content.id);
if (existing) {
return existing;
}
if (depth == this.constructor.models.length-1) {
var created = new model(data) ;
this.data[name].push(created);
return created ;
} else {
var par_name = this.constructor.models[depth+1]
.verbose_name;
var content = new this.constructor.models[data.type]();
var node = new TreeNode(data.type, content);
var par_data = data[par_name];
var created = new model(data);
var parnt = this.get_or_create(depth+1, par_data);
created[par_name] = parnt;
this.data[name].push(created);
return created ;
if (direction <= 0) {
var parent = data.parent ? this.get_or_create(data.parent, -1) : this._root;
node.parent = parent;
parent.children.push(node);
}
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) {
this.get_or_create(0, data);
this.get_or_create(data, 0);
}
}
@ -728,18 +727,19 @@ class ModelList {
* @param {class} model
* @param {Object} props Properties to match
*/
find(model, props) {
if (this.constructor.models.indexOf(model) == -1) {
return undefined ;
}
find(type, id) {
(function recurse(node) {
if (node.type === type && node.data.id === id)
return node ;
return this.data[model.verbose_name].find(function(v) {
for (let key in props) {
if (v[key] !== props[key])
return false;
for (let child of node.children) {
var result = recurse(child) ;
if (result)
return result;
}
return true;
});
return null;
})(this._root;)
}
}