model tree struct draft
This commit is contained in:
parent
02485afd9b
commit
0219d998ac
1 changed files with 46 additions and 46 deletions
|
@ -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 ;
|
||||
|
||||
for (let child of node.children) {
|
||||
var result = recurse(child) ;
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
return this.data[model.verbose_name].find(function(v) {
|
||||
for (let key in props) {
|
||||
if (v[key] !== props[key])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return null;
|
||||
})(this._root;)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue