Create ForestDisplay class

- Store templates, container and data
- All display functions removed from ModelForest
This commit is contained in:
Ludovic Stephan 2017-04-24 13:21:56 -03:00
parent 20d635137c
commit e283439ebc

View file

@ -1049,91 +1049,6 @@ class ModelForest {
this.from({});
}
/**
* Renders a node (and all its offspring) and returns the
* corresponding jQuery object.
* @param {Models.TreeNode} node
* @param {Object} templates Templates to render each model
* @param {Object} [options] Options for element render method
*/
render_element(node, templates, options) {
var modelname = node.constructor.verbose_name;
var struct_data = this.constructor.structure[modelname];
var template = templates[modelname];
var options = options || {} ;
var $container = $('<div></div>');
$container.attr('id', modelname+'-'+node.id);
var $rendered = node.display($(template), options);
$container.append($rendered);
var children = this.get_children(node);
if (children && children.length) {
if (struct_data.child_sort)
children.sort(struct_data.child_sort);
else
children.sort(children[0].constructor.compare);
for (let child of children) {
var $child = this.render_element(child, templates, options);
$container.append($child);
}
}
return $container;
}
/**
* Renders node and adds it to given container.<br>
* Assumes that the inserted node is the 'youngest'.
* @param {jQuery} $container
* @param {Models.TreeNode} node
* @param {Object} templates Templates to render each model
* @param {Object} [options] Options for element render method
*/
add_to_container($container, node, templates, options) {
var struct = this.constructor.structure;
var existing = this.get_parent(node) ;
var first_missing = node;
while (existing && !($container.find('#'+existing.modelname+'-'+existing.id))) {
first_missing = existing;
existing = this.get_parent(existing);
}
var $to_insert = this.render_element(first_missing, templates, options);
if (existing) {
$container.find('#'+existing.constructor.verbose_name+'-'+existing.id+'>:first-child')
.after($to_insert);
} else {
$container.prepend($to_insert);
}
}
/**
* Display stored data in container.
* @param {jQuery} $container
* @param {Object} templates Templates to render each model
* @param {Object} [options] Options for element render method
*/
display($container, templates, options) {
if (this.is_empty())
return;
if (this.constructor.root_sort)
this.roots.sort(this.constructor.root_sort);
else
this.roots.sort(this.roots[0].constructor.compare);
for (let root of this.roots) {
$container.append(this.render_element(root, templates, options));
}
return $container;
}
/**
* Performs for each node (in a DFS order) the callback function
@ -1184,6 +1099,22 @@ class ModelForest {
return result;
}
update(modelname, id, update_data) {
var updated = null ;
function callback(node) {
if (node.id == id) {
node.update(update_data);
updated = node ;
return true ;
}
}
this.traverse(modelname, callback);
return updated;
}
}
@ -1334,6 +1265,128 @@ class OperationList extends APIModelForest {
}
class ForestDisplay {
constructor($container, templates) {
this._templates = templates ;
this._$container = $container;
this.data = new ModelForest();
}
/**
* Renders a node (and all its offspring) and returns the
* corresponding jQuery object.
* @param {Models.TreeNode} node
* @param {Object} templates Templates to render each model
* @param {Object} [options] Options for element render method
*/
render_element(node, options) {
var modelname = node.constructor.verbose_name;
var struct_data = this.data.constructor.structure[modelname];
var template = this._templates[modelname];
var options = options || {} ;
var $container = $('<div></div>');
$container.attr('id', modelname+'-'+node.id);
var $rendered = node.display($(template), options);
$container.append($rendered);
var children = this.data.get_children(node);
if (children && children.length) {
if (struct_data.child_sort)
children.sort(struct_data.child_sort);
else
children.sort(children[0].constructor.compare);
for (let child of children) {
var $child = this.render_element(child, options);
$container.append($child);
}
}
return $container;
}
/**
* Renders node and adds it to the container.<br>
* Assumes that the inserted node is the 'youngest'.
* @param {Models.TreeNode} node
* @param {Object} [options] Options for element render method
*/
add(node, options) {
var struct = this.data.constructor.structure;
var existing = this.data.get_parent(node) ;
var first_missing = node;
while (existing && !(this._$container.find('#'+existing.modelname+'-'+existing.id))) {
first_missing = existing;
existing = this.data.get_parent(existing);
}
var $to_insert = this.render_element(first_missing, options);
//TODO better placement
if (existing) {
this._$container.find('#'+existing.constructor.verbose_name+'-'+existing.id+'>:first-child')
.after($to_insert);
} else {
this._$container.prepend($to_insert);
}
}
/**
* Updates stored data and displays it in container.
* @param {Models.ModelForest} data
* @param {Object} [options] Options for element render method
*/
render(data, options) {
if (data) {
this.data = data;
}
var forest = this.data ;
if (forest.is_empty())
return;
if (forest.constructor.root_sort)
forest.roots.sort(forest.constructor.root_sort);
else
forest.roots.sort(forest.roots[0].constructor.compare);
for (let root of forest.roots) {
this._$container.append(this.render_element(root, options));
}
return this._$container;
}
/**
* Updates the display with same modelname and id as the given data.
* @param {Object} data
*/
update(data) {
var modelname = data.constructor.verbose_name ;
var $new_elt = data.display($(this._templates[modelname]), {});
var $to_replace = this._$container.find('#'+modelname+'-'+data.id+'>:first-child');
$to_replace.replaceWith($new_elt);
}
/**
* Clears all elements from container
*/
clear() {
this._$container.html('');
}
}
/* ---------- ---------- */
/**