【JS 设计模式 】用组合模式来实现树形导航--JS代码结构思路分析(二)

【JS 设计模式 】用组合模式来实现树形导航--代码结构思路分析(一)

根据上一节中的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元素或其它标称的元素呢?
第一点:我们希望把它下的子节点加入document文档流中,不把当前创建的节点加入进去;
第二点:在构造函数中我们是要同时添加二个子节点,不希望创建一个无用的节点,document.createDocumentFrament代表创建一个空的节点,且占用当前文档节点流,当把它给别一个节点时,它会把它下面的子节点拿出来,而不是它;

下面这二句代码表示创建一个节点DOM,

var panel = document.createElement("div");
panel.setAttribute("class", (last ? "tree-folder last" : "tree-folder"));

这二句对应的是div元素:

下面二句代码:b表示Composite的图片,i表示是一个节点的关系图片;

 var b = document.createElement("b");
  var i = document.createElement("i"); 

下面代码表示创建一个包含节点名称的链接DOM元素;

var link = document.createElement("a");
  link.setAttribute("class", "folder");
  link.href = "#";
  link.innerHTML = name + "[" + total + "]";
  link.id = id;  

上面有了当前节点元素了,我们还需要创建一个它的子节点的父节点元素,意思就是它的子节点都要包含在child节点中,如下代码:

 var child = document.createElement("div");
  child.setAttribute("class", "tree-child");  

下面代码表示如果是第一层节点的话,我们不希望看到它前同有一个节点层次关系图片:

 if (level) {
    panel.appendChild(i);
  } 

上面我们创建了一个节点的最外层DOM(panel),这时我们要把这些创建的元素添加到panel中去,

  panel.appendChild(b);
  panel.appendChild(link);  

下面代码是把创建的当前节点和它的子节点的父节点,包含在root中,root是一个空节点。到这里才能说明,我们为什么要用document.createDocumentFrament()它了。

  root.appendChild(panel);
  root.appendChild(child);  

下面代码,第一句是把子节点的父节点给当前对象child属性,第二句是把root节点给当前对象element属性 ,它代表当前节点的DOM;

this.child = child;
this.element = root;  

在TreeComposite对象的原型中还有二个方法 :

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下打印的效果 :

这一节我们是通过手动地添加元素;下一节我们讲分析根据后端人员给出一个JSON格式数据,我们如何来组装起来,下一节我们可会用到递归的概念。

时间: 2024-10-18 01:38:03

【JS 设计模式 】用组合模式来实现树形导航--JS代码结构思路分析(二)的相关文章

【JS 设计模式 】用组合模式来实现树形导航--代码结构思路分析(一)

树导航效果图: 组合模式的描述: 将对象组合成树形结构以表示"部分-整体"的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性. 我们把部分用Leaf表示, 把整体用Composite表示.组合模式是有一定规律的,在实现树导航的情况下,Composite需要包含一个以上Leaf,也可以包含一个以上Leaf和一个以Composite,为什么说要包含一个以上的,如果Composite不包含任何子child的话那么它就是Leaf,Leaf表示是最后一层结节. 树形导航代码片段:

每天一个设计模式之组合模式

作者按:<每天一个设计模式>旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现.诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) 原文地址是:<每天一个设计模式之组合模式> 欢迎关注个人技术博客:godbmw.com.每周 1 篇原创技术分享!开源教程(webpack.设计模式).面试刷题(偏前端).知识整理(每周零碎),欢迎长期关注! 如果您也想进行知识整理 + 搭建功能完善/设计简约/快速启动的个人博客,请直接戳the

设计模式之组合模式(Composite)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

设计模式之组合模式(Composite)

1.定义 组合模式(Composite Pattern)也叫合成模式,将对象组合成树形结构以表示"整体-部分"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.通用类图 Component抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性. Leaf叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位. Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构. 3.通用源代码 package Compo

java设计模式之组合模式

树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题,组合模式通过一种巧妙的设计方案使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致性地处理树形结构中的叶子节点(不包含子节点的节点)和容器节点(包含子节点的节点).下面将学习这种用于处理树形结构的组合模式. 11.1 设计杀毒软件的框架结构 Sunny软件公司欲开发一个杀毒(AntiVirus)软件,该软件既可以对某

c++设计模式15 --组合模式

今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合模式的类图一本结构 想了很久,结合源代码,才搞明白,其实这个组合,意思就是说,如果我们要做这种树状结果,比如公司想让我们吧所有部门人员的 姓名,职位,薪水遍历出来,这个时候怎么办呢?那我们看树状机构图,有叶子结点和枝干结点,2种,但是2种有共性,那就是每个结点都有姓名,职位,薪水.所有叶子结点和枝干

设计模式之组合模式(Composite Pattern)

一.什么是组合模式? 组合模式提供了一种层级结构,并允许我们忽略对象与对象集合之间的差别 调用者并不知道手里的东西是一个对象还是一组对象,不过没关系,在组合模式中,调用者本来就不需要知道这些 二.举个例子 假设我们要去描述文件系统,文件系统里有文件和文件夹,文件夹里又有文件夹和文件... 没错,这是一个层级结构,就像菜单一样,菜单里有菜单项和子菜单,子菜单里有菜单项和子子菜单.. 层级结构也就是树形结构,我们很容易想到定义一个Node类,包含一组指向孩子的指针,以此构造一颗完整的树 那么我们的类

C#设计模式:组合模式(Composite Pattern)

一,C#设计模式:组合模式(Composite Pattern) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _9.组合模式 { //组合模式主要用来处理一类具有"容器特征"的对象--即它们在充当对象的同时,又可以作为容器包含其他多个对象. //组合模式,将对象组合成树形结构以表示

Java进阶篇设计模式之六 ----- 组合模式和过滤器模式

前言 在上一篇中我们学习了结构型模式的外观模式和装饰器模式.本篇则来学习下组合模式和过滤器模式. 组合模式 简介 组合模式是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 简单来说的话,就是根据树形结构把相似的对象进行组合,然后表示该部分是用来做啥的.在中有个很形象的例子,就是电脑中的 文件系统. 文件系统由目录和文件组成.每个目录都可以装内容.目录的内容可以是文件,也可以是目录.按照