最近项目需要做一个类似网盘的东西,然后有个功能是,浏览文件的时候能够返回之前的目录。因为以前没接触过,思考了许久,终于算是实现了,特此记录一下。

首先说一下什么是面包屑:
在bootstrap官网中这么描述的:在一个带有层次的导航结构中标明当前页面的位置。
类似下图:





elementplus面包屑导航 隐藏 handleLink 面包屑导航实现_当前路径


实现这个功能是必要的,因为用户如果点进一个文件夹,发现没有想看的文件,可此时一个一个往回点又太麻烦,所以需要一个面包屑路径,帮助用户快速回到之前的文件夹。

先来看看实现后的样子:



elementplus面包屑导航 隐藏 handleLink 面包屑导航实现_数据_02


点击Team01的文件夹会返回上一级:




elementplus面包屑导航 隐藏 handleLink 面包屑导航实现_数据_03


下面来看实现思路:

一、数据库设计

两张表:文件信息表和文件关系表
文件信息表用于存放文件的信息,比如ID,大小,名称等等。
文件关系表用于描述文件之间的父子关系。

数据如下:



elementplus面包屑导航 隐藏 handleLink 面包屑导航实现_数据_04


文件信息表



elementplus面包屑导航 隐藏 handleLink 面包屑导航实现_文档管理_05


文件关系表


二、后台设计

后台使用MVC模式,所以只贴controller层的代码,并讲一下逻辑就好了。

因为我们点击之前的路径时,需要知道文件ID才能去数据库查,需要知道当前路径才能更新面包屑。
所以通过生成<input type="hidden"/>标签,在这个标签里放置文件ID列表和文件路径列表。类似这样:



elementplus面包屑导航 隐藏 handleLink 面包屑导航实现_数据_06


可以看到这两个input标签的value中存放着我们需要的数据。这样就为实现这个功能做好了数据准备。

后台接受四个参数: 文件ID,当前路径,当前路径对应的ID序列,当前路径对应的路径序列。得到之后,进行拼接后通过EL表达式将拼接后的路径写到input里。

同时还要修改面包屑的<a>标签的href:




elementplus面包屑导航 隐藏 handleLink 面包屑导航实现_数据_07


怎么修改这个href呢?我们要保证之前的链接的ID序列和路径序列要恢复原样,也就是要比后面的链接短。举个例子:

面包屑:path1 -> path2 -> path3
文件夹ID序列:3 ->5 -> 7
路径序列: path1 ->path2 -> path3

假设现在处于path3层级。点了path1。那么此时文件夹ID序列和路径序列必须恢复到path1时候的样子。即:
面包屑:path1
文件夹ID序列:3
路径序列: path1

所以我们需要对这两个序列进行截取,然后拼接到<a>标签的href属性上。

思路大致就是这样,相关代码如下:

controller代码:

@RequestMapping(value = "/getsubfiles.do")
    public String getSubFilesByFileID(HttpServletRequest request, @RequestParam(value = "fileID") String fileID,
            @RequestParam(value = "curPath") String curpath, @RequestParam(value = "pathStr") String pathStr,
            @RequestParam(value = "idStr") String idStr) {

        List<FileInfo> subFiles = fileService.querySubFilesByFileID(fileID);
        FileBreadCrumb fileBreadCrumb = new FileBreadCrumb();

        String newPathStr = pathStr + "," + curpath;
        String newidStr = idStr + "," + fileID;
        fileBreadCrumb.setPathStr(newPathStr);
        fileBreadCrumb.setIdStr(newidStr);
        ArrayList<String> arrayList = new ArrayList<String>();
        String[] split = newPathStr.split(",");
        for (int i = 1; i < split.length; i++) {
            arrayList.add(split[i]);
        }

        request.setAttribute("breadcrumb", fileBreadCrumb);
        request.setAttribute("breadPath", arrayList);
        request.setAttribute("fileList", subFiles);
        if (subFiles == null) {
            System.out.println("该文件夹没有没有子文件");
        }
        return "online-disk";
    }

JavaScript代码:

/**
 * 文档管理JS
 */
$(function() {
    
    // 修改文件夹的链接地址
    var pathStr = $("#forbreadcrumbpath").attr("value");
    var idStr = $("#forbreadcrumbid").attr("value");
    $("a.filelist").each(function(key,value){
        $(this).attr("href",$(this).attr("href")+"&pathStr="+pathStr+"&idStr="+idStr);
    })
    
    var paths = pathStr.split(",");
    var ids  = idStr.split(",");
    // 修改面包屑的链接地址
    $("a.breadlist").each(function(key,value){
        // alert($(this).attr("href"));
        var pathStr_temp="";
        var idStr_temp="";
        for (var i=0;i<key+1;i++){
             pathStr_temp = pathStr_temp+ paths[i]+",";
             idStr_temp = idStr_temp+ids[i]+",";
        }
        if (pathStr_temp.charAt(pathStr_temp.length-1)==",") {
            pathStr_temp= pathStr_temp.substring(0,pathStr_temp.length-1);
            idStr_temp = idStr_temp.substring(0,idStr_temp.length-1);
        }
        $(this).attr("href",$(this).attr("href")+"fileID="+ids[key+1]+"&curPath="+paths[key+1]+"&pathStr="+pathStr_temp+"&idStr="+idStr_temp);
        //alert(paths[key+1]+":"+ids[key+1]);
    })
});

JSP相关代码:

<input type="hidden" id="forbreadcrumbpath" value="${breadcrumb.pathStr}" />
<input type="hidden" id="forbreadcrumbid" value="${breadcrumb.idStr}" />

<ol class="breadcrumb">
        <li >
                <i class="fa fa-home"></i>文档管理
         </li>
          <c:forEach items="${breadPath}" var="iter_path">
                   <li>
                     <a class="breadlist" href="getsubfiles.do?">${iter_path }</a> 
                   </li>
          </c:forEach>
</ol>