文章目录

  • 《Web应用基础》课程结业报告
    • 内容介绍
      • 效果图
    • 开发过程
      • 环境搭建
        • 开发工具
        • 环境准备
      • 需求分析
      • 各模块功能实现
        • 整体项目目录结构
        • 实体类
        • 公共视图组件
        • 业务类
        • 功能组件
          • add-word组件
          • translation组件
          • word-search组件
          • update-word组件
          • words组件
          • individual组件
    • 遇到的问题和未解决的问题
      • 遇到的问题
      • 未解决的问题
    • 改进
    • 总结

《Web应用基础》课程结业报告

内容介绍

此次结业作业的网站使用 angular+MBD开发,主题为word-corner,是关于记单词的一个网站,通过angular教程中的angular-in-memory-web-api模块,模拟实现单词信息的CRUD功能。同时,通过调用有道翻译的api,实现了中英互译的功能。

效果图

  • 首页
  • 词汇表
  • 我的
  • 添加单词
  • 修改单词
  • 删除单词
  • 搜索单词

  • 翻译功能

开发过程

环境搭建

开发工具

  • vscode

环境准备

  • nodejs
  • npm
  • angular
  • MDB
  • jquery
  • crypto-js

需求分析

通过路由功能实现SPA页面,页面顶部是导航栏,分别有主页,词汇表,我的,三个主体内容的导航。同时有一个独立于其他模块的翻译功能的实现。并在导航栏中提供该功能。
词汇表模块,实现单词的增删改查功能,采用手风琴样式,使每点击一个手风琴,可以查看该单词的详细信息,提供删除,修改单词信息的功能的按钮,和添加到的按钮。整个页面的右下角采用绝对定位的方式,提供一个添加单词信息的按钮。以实现单词信息的添加。导航栏最右侧提供一个输入框,用以模糊搜索已有单词,并可点击以显示该单词的详细信息。添加单词,修改单词,删除单词的提示框,单词详细信息的显示,都采用模态框的形式展示。

各模块功能实现

整体项目目录结构

├─component
│ ├─add-word
│ ├─individual
│ ├─translation
│ ├─update-word
│ ├─word-search
│ └─words
├─entity
├─service
└─view
    ├─footer
    ├─home
    │ └─img
    └─navbar
这是整个项目的目录结构,分为实体文件夹,服务文件夹,公共视图文件夹。组件文件夹。

实体类

实体文件夹里有两个ts文件。分别为一个单词类。和一个词意类。其中单词类依赖于词意类

// Word.ts类
export interface Word {id: number;english: string;meaning: string[];exampleSentence: ExampleSentence[];
}//ExampleSentence类
export interface ExampleSentence {originalText: string;translation: string;
}

公共视图组件

公共视图组件中有navbar ,home, footer三个组件。可能是我审美不好,做不出好看的footer,感觉加上了footer之后并不是特别美观(尽管不加也不美观)后来在最后的成品中,没有加入footer视图。
由于是一些存html代码,比较繁多,这里就不贴出代码了。

业务类

业务类一共有两个,一个是 in-memory-data.service.ts用于将数据存在内存中,模拟出数据的增删改查功能。具体代码与angular的英雄之旅教程没有什么差别。也就不贴代码了。
另一个是word.service.ts。用于实现单词的增删改查功能。
这里的增删改查功能代码与angular的英雄之旅教程也无太大不同。

功能组件

add-word组件

该组件提供增加单词信息的功能
主要有以下几个业务函数

//添加单词,
addWord(): void {const word: any = document.getElementById('word');//判断添加单词模态框中的单词是否为空,以及是否是一个合法的单词。if (word.value.length <= 0) {window.alert('添加失败,请输入单词!');return;} else if (!this.isWord(word.value)) {window.alert('添加失败,请正确输入单词!');return;}let english: string = word.value;const mean: any = document.querySelectorAll('.mean');let meaning: string[] = [];//  将单词词意输入框的单词词意取出,push进meaning字符数组中for (let i = 0; i < mean.length; ++i) {if (mean[i].value.length > 0) {meaning.push(mean[i].value);}}const exampleOrigin: any = document.querySelectorAll('.exampleOrigin');const exampleTrans: any = document.querySelectorAll('.exampleTrans');let oringin: string = '';let trans: string = '';let exampleSentence: ExampleSentence[] = [];//将单词例句输入框中的例句取出,分别将英文例句和翻译辅助给origin和trans//再将origin和trans push进exampleSentence数组中。for (let j = 0; j < exampleOrigin.length; ++j) {if (exampleOrigin[j].value.length > 0) {oringin = exampleOrigin[j].value;trans = exampleTrans[j].value;exampleSentence.push({ originalText: oringin, translation: trans });}}//采用类型推断,将整个单词信息传给父组件wordthis.addedWord.emit({ english, meaning, exampleSentence } as Word);
}
//通过正则表达式判断单词是否合法的私有函数。
private isWord(): boolean;
//用于在界面中点击添加单词词意按钮绑定的函数
addMean(): void;
//界面中点击添加单词例句按钮绑定的函数
addExample(): void;
//每次添加完单词信息后,将上一次的信息清空
remove(): void;
clear(): void;
translation组件

通过调用有道翻译api实现翻译功能
首先取有道智云官网申请账号,并开通翻译服务。注册账号即赠送50元体验金,足够支撑日常的翻译功能。也可以使用百度翻译api,每月赠送一定量的翻译词条数。
然后查看api文档并实现需求功能。

translation(): void {this.closePanel('');const translation: any = document.getElementById('translation');const query = translation.value;if (query === this.last && !this.isClear) {return;}this.last = query;if (query.length <= 0) {return;} else if (this.isAllSpace(query)) {return;}//前面的代码为一些细节处理,如判断判读输入框是否为空,是否全为空格。以及是否多次点击翻译按钮//调用api的主要函数。主要通过ajax异步调用有道翻译api。以jsonp解决跨越问题。
//主要参数即代码示例可自行查看官方文档。const key = 'CyHqYaUzMA7zUDMut0NtdIyGCbz84Eri';let from = '';let to = '';if (this.isChinese(query)) {from = 'zh-CHS';to = 'en';} else {from = 'en';to = 'zh-CHS';}const appKey = '21118fa96938a752';const salt = (new Date()).getTime();const curtime = Math.round(new Date().getTime() / 1000);const str1 = appKey + this.truncate(query) + salt + curtime + keyvar sign = CryptoJS.SHA256(str1).toString(CryptoJS.enc.Hex);$.ajax({url: 'https://openapi.youdao.com/api',type: 'post',dataType: 'jsonp',data: {q: query,appKey: appKey,salt: salt,from: from,to: to,sign: sign,signType: "v3",curtime: curtime,strick: false,},success: function (data) {//  成功调用后的执行函数。主要功能是将响应的翻译内容添加到界面中。//这一部分代码应该将其提取出来。便于后期的维护和代码的复用。但当时好像没注意。const panel = document.getElementById('panel');const hrHead = document.createElement('hr');const div: any = document.createElement('div');div.setAttribute('class', 'card-body text-dark');const h5: any = document.createElement('h5');h5.setAttribute('class', 'card-title text-center');h5.innerText = data.query;div.appendChild(h5);div.appendChild(hrHead);if (data.isWord) {if (data.basic.phonetic != undefined) {const p: any = document.createElement('p');p.setAttribute('class', 'card-text');p.innerText = '发音:' + '[' + data.basic.phonetic + ']';div.appendChild(p);const hr = document.createElement('hr');div.appendChild(hr);}for (const explain of data.basic.explains) {const p: any = document.createElement('p');p.setAttribute('class', 'card-text');p.innerText = explain;div.appendChild(p);const hr = document.createElement('hr');div.appendChild(hr);}} else {for (const meaning of data.translation) {const p: any = document.createElement('p');p.setAttribute('class', 'card-text');p.innerText = meaning;div.appendChild(p);const hr = document.createElement('hr');div.appendChild(hr);}}panel.appendChild(div);}});this.isClear = false;}//当输入框中无内容是,应该将上一次翻译的显示内容清空closePanel(query: string): void {if (query.length <= 0) {const panel = document.getElementById('panel');for (let i = 0; i < panel.children.length; ++i) {panel.removeChild(panel.firstChild);}}this.isClear = true;}isChinese(text: string): boolean {text = text.trim();const re = /^[\u4e00-\u9fa5]+$/;if (!re.test(text)) {return false;}return true;}isAllSpace(text: string): boolean {const re = /^\s+$/;if (!re.test(text)) {return false;}return true;}//官方提供的函数。truncate(q) {var len = q.length;if (len <= 20) return q;return q.substring(0, 10) + len + q.substring(len - 10, len);}
word-search组件

该组件的业务函数和angular官网教程无太大差别。略过

update-word组件

该组件业务函数与add-word组件的函数相似。只是多了一个showInfo()函数。
该组件并未使用angular的双向数值绑定语法,因为考虑到可能后在已有的单词信息基础上,添加新的例句的功能。所以,是通过用户修改了单词之后,再获取修改后的单词信息,然后通过wordService服务修改内存中的单词信息。

words组件

该组件用于显示所有单词信息的组件。采用angulard 迭代语句*ngFor将内存中的单词信息以手风琴的样式显示。

 words: Word[];deleteWord: Word;constructor(private wordService: WordService, private location: Location) { }ngOnInit(): void {this.getWords();}//获取单词getWords(): void {this.wordService.getWords().subscribe((words) => {this.words = words;});}//删除单词delete(word: Word): void {if (word != null) {this.words = this.words.filter(w => w !== word);this.wordService.deleteWord(word).subscribe();}this.deleteWord = null;}
individual组件

该组件与words组件相似,只是未提供增加单词和修改单词的功能。

遇到的问题和未解决的问题

遇到的问题

  1. 在构思好需要做什么,搭建完环境,并且设计了“数据库”之后,始终无法从in-memory-data.service.ts中获取单词信息。由此调试了两天,在csdn和百度搜寻解决方案无果。并多次从新搭建环境,多次将angular中英雄之旅教程再次学习。还是无法获取单词信息并展示。
    错误信息:
ERROR TypeError: Cannot read property 'toLowerCase' of undefinedat HttpXsrfInterceptor.push../node_modules/@angular/common/fesm5/http.js.HttpXsrfInterceptor.intercept (http.js:1718)at HttpInterceptorHandler.push../node_modules/@angular/common/fesm5/http.js.HttpInterceptorHandler.handle (http.js:1134)at HttpInterceptingHandler.push../node_modules/@angular/common/fesm5/http.js.HttpInterceptingHandler.handle (http.js:1769)at MergeMapSubscriber.project (http.js:974)at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (mergeMap.js:61)at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (mergeMap.js:51)at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)at Observable._subscribe (scalar.js:5)at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:43)at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:29)

问题的解决:最终在stackoverflow社区中找到和我遇到相似问题的解决办法。原因是 url应该是string类型 当时定义url错写为 private url: ‘api/words’ 解决办法 private url = ‘api/words’

其余问题都是一些业务逻辑上的处理问题。大都经过自己的手动测试发现并解决了。但也可能还有一些bug未发现。功能的细节处理上也不完善。

未解决的问题

将单词信息添加到 我的。这一功能未能实现。因为individual组件和words组件是两个独立的组件。而angular组件间通信我只知道有父子之间的通信。通过查阅资料发现可以通过共同父组件实现两个兄弟组件的通信。但这两个组件之间仅仅是两个放在导航栏中的路由链接而有一些联系。而目前还没有找到解决办法实现这两个组件的通信。

改进

在写结业报告时,发现可以有一些改进和完善的地方。
比如:
add-word组件和update-word组件中的几个添加输入框的函数可以提取出来作为一个服务注入到两个组件中供其使用。
翻译功能原本作为一个独立的模块,可以和词汇表功能联系起来。即可以将翻译的结果作为单词信息添加到词汇表中。
同时翻译模块还可以提供英语的读音等功能。

总结

本次web结业作业学习了angular这个前端框架。对前端页面模块化。还有通过路由实现SPA页面有了一定的了解。同时学会了如何将自己的web页面托管到免费的服务器上。同时,相比学习c++ ,java等编程语言要花很久时间很大功夫才能看到自己的成果。web的学习能更快的完成自己的成果,更容易获得成就感。

《Web应用基础》课程结业报告相关推荐

  1. 通信软件开发与应用课程结业报告

    通信软件开发与应用课程结业报告 一. 任务要求 二. 效果展示 1.主页面 2.子页面设计 (1)人物介绍子页面 (2)主题曲介绍子界面 三. 实现过程 1.主页面 (1)导航条以及首页全屏图片显示 ...

  2. android五子棋设计报告,基于安卓开发的五子棋课程设计报告精选.doc

    基于安卓开发的五子棋课程设计报告精选 大庆师范学院 <Android开发基础> 题目:基于安卓开发的五子棋游戏 专业班级: 计算机科学与技术一班 设 计 者: kkkkkkkkkkkkkk ...

  3. 大学android五子棋课程目的,基于安卓开发的五子棋课程设计报告..docx

    大庆师范学院 <ANDROID开发基础> 题目:基于安卓开发的五 子棋游戏 专业班级: 计算机科学与技术一班 设计者: KKKKKKKKKKKKKKKKKKK 指导老师:2016-2017 ...

  4. 【无标题】通信软件开发及应用

    <通信软件开发及应用> 一.做的什么 1.1任务要求 任务一:构建一个静态或动态网站.以下要求中任选A或B,要求如下: A. 静态网站 采用纯 CSS 或你喜欢的任何 CSS 框架如 Bo ...

  5. 《通信软件开发及应用》

    <通信软件开发及应用> 一.做的什么 1.1任务要求 任务一:构建一个静态或动态网站.以下要求中任选A或B,要求如下: A. 静态网站 采用纯 CSS 或你喜欢的任何 CSS 框架如 Bo ...

  6. 《Web应用基础》结业报告

    <Web应用基础开发与应用>结业报告 文章目录 <Web应用基础开发与应用>结业报告 前言 网站介绍 开发过程 1.网页背景设置 2.MDB付费内容获取 3.设计主页面: 4. ...

  7. Web前端开发技术课程实验报告实验3:Vue路由实验

    实验代码:实验3第2题实验参考.rar-互联网文档类资源-CSDN下载 Web前端开发技术课程实验报告 实验3:Vue路由实验 姓名:_ __ _ ___ ___   班级:_ _ _ ___ _ _ ...

  8. 基于JavaSwing开发模拟电梯系统+分析报告 课程设计 大作业源码

    基于JavaSwing开发模拟电梯系统+分析报告:   (大作业) 开发环境: Windows操作系统 开发工具: MyEclipse+Jdk 运行效果图: 基于JavaSwing开发模拟电梯系统+分 ...

  9. 五邑大学安卓开发程序设计报告_五邑大学模拟电路课程设计报告模板.docx

    五邑大学模拟电路课程设计报告模板 模拟电路课程设计 PAGE10 / NUMPAGES10 模拟电路课程设计报告 课程题目:二阶低通滤波器和50HZ陷波滤波器 院系名称: 专业名称: 班级: 学号: ...

  10. c语言开发一个学生成绩统计程序,用C语言实现成绩统计程序的设计课程设计报告.doc...

    武汉理工大学华夏学院 课程设计报告书 课程名称: 数据结构课程设计 题 目:用C语言实现成绩统计程序的设计 系 名: 信息工程系 专业班级: 计算机1121 姓 名: 学 号: 指导教师: 20**年 ...

最新文章

  1. LeetCode 369. Plus One Linked List--链表--C++,Python解法
  2. mybatis的执行流程
  3. 请你讲一讲JavaScript有哪些数据类型, 数据类型判断有哪些方法?
  4. linux 7自定义服务,CentOS 7.x设置自定义开机启动,添加自定义系统服务
  5. 2018年华为软件精英挑战赛-初赛赛题
  6. 实用工具软件远古大神Nir Sofer,数百款短小精悍便携工具,从Win2000到Win10通吃
  7. Spring学习笔记
  8. 脚本 金盾替换机器码_金盾2018SS加密视频机器码替换工具的分析过程三
  9. java m个苹果n个篮子_m个苹果放在n个盘子中有多少种结果
  10. 一种基于FBO实现渲染流水线的思路
  11. mysql v8 漏洞_海洋CMS V8.7 SQL注入漏洞
  12. hive优化——严格模式
  13. MathType如何编辑商标标志
  14. 美国南加州大学骆沁毅:构建高性能的异构分布式训练算法
  15. 记工作的第一月--光说不练,假把式
  16. 保持精力旺盛的25招 送给奋斗的男人 (转)
  17. python中双向索引_Python 字典支持双向索引。Python 集合也支持双向索引
  18. python_操作linux上的mysql
  19. 王兴:淘宝为什么还不支持微信支付?
  20. 广东省一本大学哪些学计算机,广东九所一本高校填报攻略

热门文章

  1. BackgroundWorker的参数传递
  2. c 语言鼠标钩子,线程钩子(鼠标钩子) | C/C++程序员之家
  3. Windows如何刷新DNS缓存
  4. 新版智能广告点击要饭网单页网站源码
  5. 电子商务平台搭建方案
  6. ATV 开发 三 DRM技术简介
  7. 联想小新13pro锐龙版网卡_诠释极致性价比 联想小新Pro 13标压锐龙版笔记本评测...
  8. 如何激活win10系统?小白们无需到处问东问西了!
  9. 播放m3u8视频,用小米浏览器播放m3u8视频
  10. LoadRunner压力测试:测试报告