根据上一节中的HTML代码结构我们通过JS来渲染HTML代码,我们先提供一下JS的代码片段,这代码代码不是一个完整的代码是经过简化的。通过JS代码来分析如何组装HTML的
Composite类型的代码:
function TreeComposite(id, name, total, level, last) { var root = document.createDocumentFragment(); var panel = document.createElement("div"); panel.setAttribute("class", (last ? "tree-folder last" : "tree-folder")); var b = document.createElement("b"); var i = document.createElement("i"); var link = document.createElement("a"); link.setAttribute("class", "folder"); link.href = "#"; link.innerHTML = name + "[" + total + "]"; link.id = id; var child = document.createElement("div"); child.setAttribute("class", "tree-child"); if (level) { panel.appendChild(i); } panel.appendChild(b); panel.appendChild(link); root.appendChild(panel); root.appendChild(child); this.child = child; this.element = root; } TreeComposite.prototype = { addNode: function (treeNode) { this.child.appendChild(treeNode.getElement()); }, getElement: function () { return this.element; } }
我们先来分析一下面上面的代码片段:
TreeComposite是有一个带有参数的构造函数,它需要传入四个参数:
id:当前节点的主键(交互时用到);
name:当前节点的名称;
total:当前节点下的记录条数,不是表达他的子节点哦,这里要注意一下;
level:代表树导航的深度的层次级别,越向内级别越高;
last:当前节点是否是父节点下的子节点的最后一个节点;
我们知道了构造函数中参数代表的含义,接下下我们看一下构造函数中的代码片段
首先构造函数的第一句代码是:
var root = document.createDocumentFragment();为什么要创建一个这样的节点,而不是创建一个div元素或其它标称的元素呢?
var panel = document.createElement("div"); panel.setAttribute("class", (last ? "tree-folder last" : "tree-folder"));
下面二句代码:b表示Composite的图片,i表示是一个节点的关系图片;
var b = document.createElement("b"); var i = document.createElement("i");
var link = document.createElement("a"); link.setAttribute("class", "folder"); link.href = "#"; link.innerHTML = name + "[" + total + "]"; link.id = id;
var child = document.createElement("div"); child.setAttribute("class", "tree-child");
if (level) { panel.appendChild(i); }
panel.appendChild(b); panel.appendChild(link);
root.appendChild(panel); root.appendChild(child);
this.child = child; this.element = root;
addNode: function (treeNode) { this.child.appendChild(treeNode.getElement()); }, getElement: function () { return this.element; }原因组合模式是有“部分-整体”的层次结构的,addNode方法是把它的子节点(Composite或 Leaf)添加到这个child中去;getElement方法是获取当前对象的节点;
Leaf类型的代码:
function TreeLeaf(id, name, total, level, last) { var panel = document.createElement("div"); panel.setAttribute("class", (last ? "tree-only last" : "tree-only")); var b = document.createElement("b"); var i = document.createElement("i"); var link = document.createElement("a"); link.setAttribute("class", (total ? "folder" : "folder empty")); link.href = "#"; link.innerHTML = name + "[" + total + "]"; link.id = id; panel.appendChild(i); panel.appendChild(link); this.element = panel; } TreeLeaf.prototype = { addNode: function (treeNode) { }, getElement: function () { return this.element; } }
我们先来分析一下面上面的代码片段:
TreeLeaf是有一个带有参数的构造函数,它需要传入四个参数:
id:当前节点的主键(交互时用到);
name:当前节点的名称;
total:当前节点下的记录条数,不是表达他的子节点哦,这里要注意一下;
level:代表树导航的深度的层次级别,越向内级别越高;
last:当前节点是否是父节点下的子节点的最后一个节点;
TreeLeaf构造函数中的代码是和TreeComposite构造函数中的代码是相似的,大家可以根据TreeComposite构造函数中的代码讲解来对比着理解TreeLeaf构造函数中的代码;
根据上面的二个对象,我们来回忆一下上节讲到“将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。”这句话。
前半句我们可能好理解,是一种包含关系,谁包含着谁;
我们通过后半句来对应着代码来看一下
TreeComposite(组合对象)和TreeLeaf(单个对象)构造函数中参数的个数和顺序都是一样的,它们分别原型中的方法都是addNode和getElement。他用他们相同的方法;
我们希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象(方法),这里的方法是组合对象和单个对象都有的方法;
下面我们写一段代码对上面的二个对象的使用:
// root节点 var treeRoot = new TreeComposite(0, "全部", 8, 0, true); // 添加第一个节点 treeRoot.addNode(new TreeLeaf(0, "未分组", 1, 0, true)); // 这是第二个节点 var treeRoot1 = new TreeComposite(0, "客户", 5, 0, true); // 这是第二个节点下的二个子节点 treeRoot1.addNode(new TreeLeaf(0, "西方客户", 2, 0, true)); treeRoot1.addNode(new TreeLeaf(0, "东方客户", 0, 0, true)); // 将第二个节点添加root节点中去 treeRoot.addNode(treeRoot1); // 这是第三个节点下的二个子节点 treeRoot.addNode(new TreeLeaf(0, "修改分组名称", 2, 0, true)); // 这是第四个节点下的二个子节点 var treeRoot2 = new TreeComposite(0, "计算机", 0, 0, true); treeRoot2.addNode(new TreeLeaf(0, "硬件工程师", 0, 0, true)); treeRoot2.addNode(new TreeLeaf(0, "软件工程师", 0, 0, true)); // 将第三个节点添加root节点中去 treeRoot.addNode(treeRoot2); // 这是第五个节点下的二个子节点 treeRoot.addNode(new TreeLeaf(0, "最新添加", 0, 0, true)); // 最后打印出所有节点 console.log(treeRoot.getElement());Chrome下打印的效果 :