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); }
|
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;)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue