Доброе время суток.
Требуется изменить поведение стандартных компонентов TreeView и TreeNode из библиотеки Alloy UI (надстройка над Yahoo UI). А конкретно, требуется изменить рендер нод дерева. Для этого я заместил функцию _renderBoundingBox объекта TreeNode в своём объекте TreeNodeCustom:
_renderBoundingBox: function() {
var instance = this;
var boundingBox = instance.get('boundingBox');
var contentBox = instance.get('contentBox');
var nodeContainer = null;
if (!instance.isLeaf()) {
contentBox.append(instance.get('hitAreaEl'));
nodeContainer = instance._createNodeContainer();
}
var element = A.Node.create(ELEMENT_TPL);
// here I need the owner tree
var builderObject = instance.get('builderObject');
var nodeBuilder = instance.get('ownerTree').get('nodeBuilder');
if (!nodeBuilder) {
var err = 'Couldn\'t get builder function. Owner-tree of the TreeNodeCustom must be the TreeViewCustom.';
A.error(err, new TypeError(err));
}
var node = nodeBuilder(builderObject);
if (!(node instanceof A.Node)) {
var err = 'Wrong type of built node.';
A.error(err, new TypeError(err));
}
element.append(node);
contentBox.append(element);
boundingBox.append(contentBox);
if (nodeContainer) {
if (!instance.get('expanded')) {
nodeContainer.addClass(CSS_TREE_HIDDEN);
}
boundingBox.append(nodeContainer);
}
return boundingBox;
},
Для рендера мне нужна функция nodeBuilder, которая хранится атрибутом в объекте TreeViewCustom (корневой объект дерева). Но атрибут ownerTree устанавливается только в нодах первого уровня (хранящихся непосредственно в объекте дерева):
aui-tree-data.js
_setChildren: function(v) {
var instance = this;
var childNodes = [];
A.Array.each(v, function(node) {
if (node) {
if (!isTreeNode(node) && isObject(node)) {
// creating node from json
node = instance.createNode(node);
}
// before render the node, make sure the PARENT_NODE and OWNER_TREE references are updated
// this is required on the render phase of the TreeNode (_createNodeContainer)
// to propagate the events callback (appendChild/expand)
if (!isTreeNode(instance)) {
node.set(OWNER_TREE, instance);
}
node.render();
// avoid duplicated children on the childNodes list
if (A.Array.indexOf(childNodes, node) == -1) {
childNodes.push(node);
}
}
});
return childNodes;
}
Пришлось его тоже заместить:
_setChildren: function (v) {
var instance = this;
var childNodes = [];
A.Array.each(v, function(node) {
if (node) {
if (!isTreeNode(node) && A.Lang.isObject(node)) {
// creating node from json
node = instance.createNode(node);
}
// before render the node, make sure the PARENT_NODE and OWNER_TREE references are updated
// this is required on the render phase of the TreeNode (_createNodeContainer)
// to propagate the events callback (appendChild/expand)
node.set('ownerTree', isTreeNode(instance) ? instance.get('ownerTree') : instance);
node.set('parentNode', instance);
node.render();
// avoid duplicated children on the childNodes list
if (A.Array.indexOf(childNodes, node) == -1) {
childNodes.push(node);
}
}
});
return childNodes;
}
Это даёт желаемый результат, но замещение внутренних функций базовых объектов - не очень-то хороший подход. В то же время реализовывать полностью дерево не хотелось бы.
Фреймворк я недавно начал изучать, поэтому, возможно, просто не вижу правильного пути. Может быть кто-нить подскажет другой способ?