Meilleure gestion arbre immutable
This commit is contained in:
@@ -1,53 +1,73 @@
|
||||
var _ = require('lodash');
|
||||
var update = require('react-addons-update');
|
||||
var RecursiveIterator = require('recursive-iterator');
|
||||
|
||||
// Tree manipulation helpers
|
||||
function Tree(srcState) {
|
||||
this._keyCount = 0;
|
||||
this._state = srcState || {};
|
||||
}
|
||||
|
||||
exports.walk = function(branch, func, parent) {
|
||||
var p = Tree.prototype;
|
||||
|
||||
if(!branch) return;
|
||||
|
||||
var breakHere = func(branch, parent);
|
||||
|
||||
if(breakHere) return breakHere;
|
||||
|
||||
var items = branch.items;
|
||||
|
||||
if(!items) return;
|
||||
|
||||
for( var i = 0, item = items[i]; (item = items[i]); i++ ) {
|
||||
breakHere = exports.walk(item, func, branch);
|
||||
if(breakHere) return breakHere;
|
||||
p.get = function(pathArr) {
|
||||
var obj = this._state;
|
||||
for(var i = 0, len = pathArr.length; i < len; ++i) {
|
||||
obj = obj[pathArr[i]];
|
||||
if(!obj) throw new Error('Unexistant tree path: "'+pathArr.join('.')+'"');
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
exports.find = function(tree, obj) {
|
||||
p.update = function(pathArr, updateCommands) {
|
||||
var updateQuery = this._createUpdateQueryForPath(pathArr, updateCommands);
|
||||
this._state = update(this._state, updateQuery);
|
||||
return this;
|
||||
};
|
||||
|
||||
var result;
|
||||
|
||||
exports.walk(tree, function(item, parent) {
|
||||
if( _.isEqual(item, obj) ) {
|
||||
result = {item: item, parent: parent};
|
||||
return true;
|
||||
p.del = function(pathArr) {
|
||||
var prop = pathArr[pathArr.length-1];
|
||||
var parentPath = pathArr.slice(0, -1);
|
||||
this.update(parentPath, {
|
||||
"$apply": function(item) {
|
||||
delete item[prop];
|
||||
return item;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
exports.matches = function(tree, obj) {
|
||||
|
||||
var results = [];
|
||||
|
||||
var matches = _.matches(obj);
|
||||
|
||||
exports.walk(tree, function(item) {
|
||||
if( matches(item) ) {
|
||||
results.push(item);
|
||||
p.find = function(obj) {
|
||||
var iterator = this._getStateIterator();
|
||||
for(var item = iterator.next(); !item.done; item = iterator.next()) {
|
||||
var state = item.value;
|
||||
if(state.node === obj) {
|
||||
return state;
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
p.getState = function() {
|
||||
return this._state;
|
||||
};
|
||||
|
||||
p.toJSON = function() {
|
||||
return this._state;
|
||||
};
|
||||
|
||||
|
||||
p._getStateIterator = function() {
|
||||
var iterator = new RecursiveIterator(this._state);
|
||||
return iterator;
|
||||
};
|
||||
|
||||
p._createUpdateQueryForPath = function(pathArr, updateCommands) {
|
||||
var cursor, query = {};
|
||||
cursor = query;
|
||||
for(var i = 0, len = pathArr.length; i < len-1; ++i) {
|
||||
cursor = cursor[pathArr[i]] = {};
|
||||
}
|
||||
cursor[pathArr[pathArr.length-1]] = updateCommands;
|
||||
return query;
|
||||
};
|
||||
|
||||
module.exports = Tree;
|
||||
|
Reference in New Issue
Block a user