师生家族树(文本-->结构)
20/04/17 完成初版,累...
20/04/18 修改文章几处小错误,Github增加README.md文件
| 这个作业属于哪个课程 | 班级的链接 |
|---|---|
| 这个作业要求在哪里 | 作业要求 |
| 这个作业的目标 | 完成一个web小程序,将师生文本信息转化为师生树 |
| 作业正文 | 如下 |
| 参考文献 ① | bootstrap组件 |
| 参考文献 ② | treeview下载地址 |
| 参考文献 ③ | treeview中文API文档 |
| 参考文献 ④ | treeview官方demo |
| 参考文献 ⑤ | w3school |
| 参考文献 ⑥ | Qunit |
分工
| Item | Address |
|---|---|
| 刘超然 | 博客地址 |
| 高洁 | 博客地址 |
| Github | 仓库地址 |
刘超然:负责程序的编写和调试,重构和迭代代码,将一些想法付诸实现,完善博客技术部分内容。
高洁:负责思路的梳理、提供想法,发现问题后及时提出解决方案,完成博客陈述部分内容。
PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(min) | 实际耗时(min) |
|---|---|---|---|
| Planning | 计划 | 30 | 45 |
| Estimate | 估计这个任务需要多少时间 | 20*60 | 10*60 |
| Development | 开发 | 20*60 | 10*60 |
| Analysis | 需求分析 (包括学习新技术) | 2*60 | 2*60 |
| Design Spec | 生成设计文档 | 20 | 30 |
| Design Review | 设计复审 | 10 | 15 |
| Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 15 |
| Design | 具体设计 | 2*60 | 60 |
| Coding | 具体编码 | 10*60 | 6*60 |
| Code Review | 代码复审 | 20 | 60 |
| Test | 测试(自我测试,修改代码,提交修改) | 60 | 4*60 |
| Reporting | 报告 | 60 | 5*30 |
| Test Repor | 测试报告 | 30 | 30 |
| Size Measurement | 计算工作量 | 15 | 10 |
| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 15 | 10 |
| Sum | 合计 | 3530 | 2340 |
思路
思路概述
刚刚拿到问题,我们的脑海中只有❓❓❓(BGM自动响起:小朋友,你是否有很多问号...),这是要我们做什么啊,看着也太难了吧!!!冷静了一个礼拜左右,我们又重新来审视这次的作业(其实主要是因为DDL),发现也不是太难,就想着来做做吧!💦
上个学期我们学习了Java web,这些预备知识对作业来说很有帮助,因此这里需要解决的是:
- 如何得到师生信息
- 如何将学生归到老师的门下(如何生成一棵树)
- 如何显示树形结构
第一个想法
那一瞬间,MVC、Tomcat、jsp、Ajax等名词瞬间涌上心头,要不我们这么去做吧:
- 先用jsp写个界面出来,一个文本框、一个提交按钮
- 提交按钮的功能就是将文本框的信息传到后台服务器
- 使用MVC模式,前后端分离,后端处理字符串,可以使用Java来处理,还可以用Ajax来异步刷新
- Java中Collection接口中的各种实现类,足以应对作业中的字符串存储、关联等情况
- 最后百度一下Java后台数据转前端的树形结构怎么操作即可
理想很丰满,现实是:MVC、DAO、Ajax等概念忘得差不多了,Tomcat早已不存在(重装了系统)。
害!真的太难了,我再回去看看题目要求吧!突然发现了这条:
请确保其他同学在下载你的所有文件后,用谷歌浏览器运行html文件就能展现预期结果
原来题目的本意并不需要我们去搞什么服务器和数据库啊!!而是需要我们做个静态页面,使用JavaScript完成数据的处理!如果使用到服务器和数据库的话,就达不到下载文件后打开就能运行的效果了(这是我们的猜想:在一个啥都没装的电脑上,如果能完美运行,想必依赖项和附属项都是离线且无需额外的环境配置的)!
第二个想法
在第一个想法终结时,第二个想法就自然而然地出现了:
采用HTML + JavaScript + CSS去实现!
作业编码要求的第三点:使用html+css+javascript实现,可以使用bootstrap这样的框架;
(捂脸)敢情这就是作业的本意啊喂!实现思路啥的这里就不赘述了,下面都有~~
代码组织与内部实现设计
代码组织

类图

算法
对于样例而言,作业描述部分已经给了我们提示🧐:
"导师:","级博士生:","级硕士生:","级本科生:"和"、"当做关键词处理
JavaScript怎么可能没有split方法呢!
于是我们将上述关键字用split分割开来,并取有意义的部分进行存储。
当分割到学生层级时,用Js对象数组一步一步向上套娃,最终把两个值赋给JSON(treeData),完成数据的转化。具体流程图如下:
流程图

最有价值的代码片段
下面贴出个人认为最有价值的代码片段:
这是主函数中的动态增加树的核心代码,功能是将传过来的动态id,赋给一个新的div标签,最终加到HTML中,实现多颗树的共存。
被调用的流程在流程图最后有所展示,就不再赘述啦。
/*
* 该函数用于将对应的div + 动态id值插入到HTML中的大div中
*/
function add_div(treeId) {
const e = document.getElementById("tree");
const div = document.createElement("div");
div.id = treeId;
div.innerHTML = e.innerHTML;
// 在双亲div中增加孩子div,可以理解为div数组然后一直往里边加(div)
document.getElementById("tree").appendChild(div);
}
附加特点设计与展示
特点集
- 提供一键展开和关闭的按钮
- 提供节点信息的模糊搜索并高亮
- 对于不同的信息分别尾部增加不同的emoji表情(像这样)😏
- 按钮value增加特色
(抽象化)
Reason
主要就是想着在实现基本功能上多提供一些小功能~让作品显得不那么死板😪
代码一瞥
其实实现起来还是比较简单的(还不是因为调了API!),关键就在于生成树的阶段,每次生成树时存储树的id,在按下按钮后,调用对应的方法——遍历这个id数组,将所有的树都给check(调了API)一遍。
// 用于额外功能——所有div的id数组
const ids = [];
// emoji数组——small trick
const emoji = ["🧑", "👨🎓", "👨💻"];
/*
* 该函数用于展开所有树的节点
*/
function expandAllNodes() {
for (let i = 0; i < ids.length; i++)
{
$("#" + ids[i]).treeview(
'expandAll',
{
levels: 3,
silent: true
}
)
}
}
效果展示
- emoji
(抽象)效果🤓

- 展开 / 收起("看"不出来效果~~放一张好了)

- 搜索匹配

目录说明和使用说明
目录说明
继续拿上面的那张目录图来说:

本次作业用到了bootstrap框架、JQuery以及treeview这个树形结构插件,它需要bootstrap和JQuery才能正常使用。因此我们将js、css和图片都使用文件夹归类,最后放置到dist文件夹中,作为MainPage.html的静态附属资源去使用。
Github zip文件使用说明
- 下载本次作业的zip包

- 解压缩
- 得到上面的文件部署结构
- 用Chrome浏览器打开MainPage.html输入对应的文本信息即可看到效果
单元测试
工具——Qunit
其实一开始看到要进行单元测试,我是拒绝的,因为你永远不知道它到底要测试(学习)多久(才会用)......
后来,随手百度发现这个Qunit配置还是蛮方便的(下载一个Js和一个CSS即可使用),那就试试吧~
再后来...
- “啊,原来是这样啊,我会了,我会了”
- “嗯?????怎么又不可以了???”
- ”哦,我又知道了,看来是要这样写...”
- “哈?怎么还是在报错???搞我?“
- “害,官方文档,真香!”
于是最终我们搞出来这些个玩意儿:
憨憨测试函数
- 憨憨getJson内置测试函数

- 憨憨外部html测试函数

憨憨测试结果

构造思路
害,说多了都是泪,其实也没啥思路(因为Qunit用的还是一知半解),所以只能去验证比较简单的值~~写了三个憨憨函数分别验证:
- 树的个数
- 每棵树的节点个数
每棵树第一次分支的学生个数(太憨了)
嗯,这单元测试和我们预想的不太一样啊!算了算了,以后再玩吧😁!(流下了没有技术的泪水😭)
Github的代码签入记录
这就是Github🐴?爱了爱了!pull request好有意思啊!QWQ(以至于做作的来了句”Thanks“)
- fork and update

- pull request
(version还写成vesion!!摔!)

- commit

这怎么一开始就version 0.2了???哦,原来是太憨了,原仓库不会用,导致上传错误啊!🤓
遇到的困难和解决方法
啊~这该从何说起呢?可以说这一次作业是一路“跪”出来的,遇到的困难和错误真的有点多...在此就简单贴上几个吧:
困难
- treeview树形插件解决了树形结构构造的问题,那我们怎么将数据转化为treeview能够使用的数据呢?
- 单元测试不会做,用Qunit搞了半天也没有进展,各种报错


- 各种小错误,CSS显示错误、IDEA代码warning提示,$().treeview is not a function....



尝试 & 解决方法
treeview树形插件解决了树形结构构造的问题,那我们怎么将数据转化为treeview能够使用的数据呢?
- 花了一下午的时间去百度、找资料想去解决这个问题,可惜到晚饭前依旧都没有解决,当时都快要崩溃了(图1)。好在晚饭后的再次尝试,让我们取得了重大突破:将数据按照可以运行的普通数据模板(使用浏览器的调试功能可以看到数据格式)一层层嵌套,最终调用treeview运行成功!!!(图2、3)



单元测试不会做,用Qunit搞了半天也没有进展,各种报错
- 这个Qunit真是磨人的小妖精🙄我以为是路径设置错误导致无法正常调用,结果是因为它只能在主页面(html)写script去测试!!看了官网的文档后改成了憨憨写法——在被测试Js文件中写相应的get函数返回对应的值,以用于比较。
各种小错误,CSS显示错误、IDEA代码warning提示,$().treeview is not a function....
- 小错误大杂烩...解决方法分别是,导入font文件夹(目录有说哦)、换行且贴边写以及在html中导入 treeview.js(我好憨啊!)
以上错误已全部解决。
心得体会
我太憨了!
-
遇到困难不轻言放弃
真的太难了!!! -
如果一个问题死磕了很久依旧无法解决,为什么不试试休息一会吃吃东西呢?
这次作业做的贼累!! -
结对编程,共同进步!
如果结对的作业能轻松点就好了 -
其实还是有很多地方不尽人意
但是我就不改(有时间再说) -
继续努力吧!
555真的不点个赞嘛
评价你的队友
高洁:
- 值得学习的地方:总是能在不经意间提出好的想法,也总是一句话就能指出问题所在以及该如何去解决。活泼爱笑,奇思妙想。
- 需要改进的地方:提升编程能力,你要做的就是用代码实现你那些超棒的想法。

浙公网安备 33010602011771号