设为首页 | 加入收藏 | 登录 | 注册 
  • 当前位置:首页 » 新闻中心 » 行业知识库
  • 基于ajax的IETM动态目录树的设计与实现

    发布日期:2014-12-30   信息来源:来自网络  浏览次数:
     

    树形目录是IETM应用系统中常用的直接访问方式,用户通过清晰的、可折叠的树形目录可以快速定位到目标卡片或章节。这样做有两个优势:一是直观,通过树节点的展开、折叠可以很直观地了解到数据之间的层次关系。二是方便,通过点击树的节点就可以显示所需要的信息,而无需查询操作。常见的目录树有两种类型:

    一是静态目录树。在应用程序开始时一次性加载所有数据。优点:纯客户端控制,页面无需刷新。缺点:(1)一架飞机的技术手册数量繁多,所构成目录树中的条目最少也有上千条。庞大的数据量使页面显示速度迟缓,多到一定程度时,会让客户端超时以至于读取失败,严重时甚至会使IE当掉。(2)对于某个终端用户来说,经常使用的只是特定的某几类技术资料,目录中的绝大部分信息是不需要的。

    二是动态目录树。每次只加载一级目录。只有用户展开节点时,才加载下一级节点数据。优点:数据量小,响应速度快。缺点:页面频繁刷新,用户体验差,而且刷新后会使其它数据丢失。

    本文提出了一种新的解决思路:采用ajax技术构建动态的目录树。这种方法综合了前两种方法的优点,一方面数据动态加载,一次只加载一级目录,只有用户点击后才显示下一级分类目录。不仅大大减少了数据的冗余,提高了页面加载速度,而且使得每个用户都能根据实际需要构建出满足自身要求的目录树,灵活性强。另一方面采用ajax技术实现与后台服务器之间的数据交换,使得页面无需全部刷新。

    1.Ajax技术简介

    Ajax的全称是Asynchronous JavaScript and XML20052月由Adaptive Path公司提出,之后,在Google地图中得到了成功的应用,发展迅速。实际上,Ajax并不是一种新技术,而是几种技术的组合,包括:

    基于XHTMLCSS标准的表示;

    使用DocumentObjectModel进行动态显示和交互;

    使用XMLHttpRequest与服务器进行异步通信;

    使用JavaScript绑定一切。

    归纳起来说,它有两大特点:

    一是异步读取数据。Ajax技术的核心是XMLHttpRequest对象,它提供了客户端与服务器端异步通信的能力,直接通过浏览器与后端服务器进行通信,在服务器端进行数据的处理(如更新或查询数据库)

    二是页面无需全部刷新。从后台服务器返回的数据,通过JavaScriptCSS来更新页面中相应的区域。可以看出,ajax使Web应用程序无需从服务器重新载入页面来实现页面数据的更改,从而避免了传统web应用程序在提交请求后出现的“白屏”现象。

    2. IETM系统中目录树结构的构建

    2.1目录文档的结构 IETM应用系统中,技术资料以数据模块的形式存储在数据库中,每个数据模块对应一个xml文档。出版物模块则用来表示各个数据模块所属的类别和层次关系,相当于技术资料的总目录。按照S1000D标准,出版物模块的数据架构与相应的XML文档见图1

    可以看出,出版物模块中的核心信息有两类:一类是数据模块的分类信息,这一信息是通过元素pmentry之间的嵌套关系体现出来的;另一类是数据模块的内容信息,元素refdm中包含该数据模块的唯一编码。元素title根据位置的不同,代表不同的含义。如果title的下一个元素为pmentry,表示所属类别的名称;如果title的下一个元素为dmentry,表示数据模块的名称。

    2.2目录树的结构 IETM阅读系统中,目录树用于对所有技术资料进行组织、管理和导航。它描述了技术数据的总体结构框架,为用户展示了清晰的、层次分明的数据结构组织形式。目录树的结构如图2所示,基本组成单元是节点。IETM系统目录树中节点的类型又可以分成两种:父节点和叶子节点。叶子节点表示IETM系统技术资料对应的数据模块,父节点表示数据模块的所属类别。

    2.3目录文档与目录树之间的映射 出版物文档中的元素pmentrydmentry分别对应树中的父节点和叶子节点。为了使目录文档与树之间的对应关系更加清晰,便于使用xsl文件进行转换,需要对其它信息进行归类,并转换为所属元素的对应属性,使目录文档中只包含pmentrydmentry两类元素。图3是转换后的xml文档,可以看出它的层次信息十分清晰,与树结构一一对应。

    3. 基于ajax的动态目录树的实现

    3.1业务逻辑 Ajax动态目录树的业务逻辑图4所示。

    (1)前台浏览器端捕捉用户的操作事件。如果要展开节点,则通过xmlHTTP异步调用服务器端,并将所要展开节点的路径作为参数传递到服务器端。

    (2)后台服务器端根据客户端传送的节点参数,求取所有子节点的参数,包括显示的文字、有无下级节点。如果是叶子节点,那么还要计算该节点所链接数据模块的URL地址。

    (3)将获取的数据通过response写回去。

    (4)客户端接受服务器端的数据,将子节点的参数添加到所展开节点下面。

    3.2关键设计

    3.2.1客户端创建xmlHttp对象 客户端通过xmlHttp对象调用服务器,传送待展开节点的路径,并发出HTTP请求,代码如下:

          if(type of XMLHttpRequest!="undefined") //如果是IE浏览器,创建XMLHttpRequest对象

          {xmlhttp=newXMLHttpRequest()}

          else if(typeof ActiveX Object!="undefined")//否则创建XMLHTTP ActiveX对象。

         {xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")}

         else return null

         xmlhttp.open("post""pm.aspx"true)//调用服务器

         xmlhttp.onreadystatechange=function(){

                            if(req.readyState==4){

                               var xmlNodes=req.responseXML.

      firstChild//处理回传数据

                             LoadDemandNodes(xmlNodesnode)

          }      }

          xmlhttp.setRequestHeader("Content-Type""application/x-www-form-urlencoded")

          xmlhttp.send("nodePath="+nodePath)//传送待展开节点的路径

    3.2.2服务器端处理数据 服务器端调用存储过程从数据库中取出出版物模块,并根据客户端传来的待展开节点的路径对出版物模块进行过滤,取出子节点的数据,组织成特定格式的XML文档后返回到客户端。

    为了表示目录树中的节点,在服务器端创建xml元素entry,包含三个属性,见表1。同时,将出版物模块中的元素pmentrydmentry都转换为entry元素,并通过Response.Write将数据返回。

    服务器端数据处理的代码如下:

        private void StreamNodeData(XmlNode node){

        this.Response.ContentType="text/xml"

            StringBuilder sb=new StringBuilder()

            sb.Append("<entries>")

            foreach(XmlNode child in node.ChildNodes){

                if(child.Name=="pmentry")//如果是pmentry,则entry的属性childrentrue,表示父节点。

                sb.AppendFormat("<entryname='{0}'children='{1}'/

    >"child.Attributes["title"].Value"true")

            else   //如果是dmentry,则entry的属性childrenfalse,表示叶子节点,同时将该数据模块的dmc值赋予属性url

            sb.AppendFormat("<entryname='{0}'children='{1}'

    url='{2}'/>"child.Attributes["title"].Value"false"child.Attributes["

    dmc"].Value)

              }

            sb.Append("</entries>")

           this.Response.Write(sb.ToString())

           this.Response.Flush()

           this.Response.Close()}

    3.2.3客户端更新HTMLDOM 客户端通过xmlhttp.responseXML接受服务器端返回的数据并解析,从而更新HTML页面中相应位置的数据。为了表示父节点,人为加上一个节点显示Loading...,并将节点闭合,以显示与叶子节点的区别。

    客户端实现HTMLDOM更新的代码如下:

        function LoadDemandNodes(xmlNodesnode){

          for(vari=0i<xmlNodes.childNodes.lengthi++){

             var currentRecord=xmlNodes.childNodes[i]

             var url=currentRecord.getAttribute("url")

             var newChild=node.addChild(xmlNodes.childNodes[i].

    getAttribute("name"))//添加子节点

          if(newChild!=null&&xmlNodes.childNodes[i].getAttribute("

    children")=="true"){//如果是父节点,添加一个子节点。

          newChild.addChild("Loading...")

          newChild.setExpanded(false)}

        else{     //如果是叶子节点,设置url属性。

           newChild.element.childNodes[2].setAttribute("URL"url)   }

        }

          }

    3.3实现结果 通过上述方法,我们设计了某型飞机IETM阅读系统,见图5。系统中数千个数据模块的数据是分级动态加载的,页面加载速度快,并且页面的局部刷新实时稳定。

    实践证明,以上方法设计的目录树具有高效、快速、用户体验好等优点,是一种比较理想的树型目录设计方法。

    关于希盟信 | 联系我们 | 法律声明 | 网站地图

    copyright@2009-2016 西安希盟信仿真科技有限公司  陕ICP备12011946号