1、课程结业内容
《通信软件开发与应用》这门课程我主要做的是一个电影排名显示,叫做Project-Movie
。我通过对前端动态框架angular
和TOH-version 2
的学习,在TOH-version 2
的基础上做出了Project-Movie
这样的网站。
2、开发过程
首先,我在
VScode
编辑器中利用前端框架angular
在本地进行angular
官方教程英雄之旅的学习,然后自己搭建出了如下所示的网站,基本实现了数据修改的功能。然后我开始了自己的项目Project-Movie
的开发
1.电影列表及详情显示
- 对于电影列表显示,我首先创建了组件
Movies
和模拟的电影数据,然后在该组件类文件中直接赋值得到模拟的电影数据,再在模板文件中使用*ngFor
循环显示所有的电影。 - 对于电影详情显示,我也创建了组件
MovieDetail
,用来显示用户点击的电影详情;当用户从列表中选择了某个电影时,父组件MoviesComponent
将通过把要显示的电影发送给子组件MovieDetailComponent
,来控制子组件进行显示该电影的详细信息。
2.添加服务及路由
- 由于
angular
中的组件不应该直接获取或保存数据,即它们不应该了解是否在展示假数据,而应该聚焦于展示数据,把数据访问的职责委托给某个服务。因此我这里新建了服务MovieServie
用于提供电影数据的获取,包括从云服务器获取所有的电影信息、获取用户点击的单个电影详细信息、增加/删除/修改电影的信息。目前主要从模拟的电影数据中使用RxJS
的of()
函数来模拟从服务器返回数据。 - 在常见的前端静态框架中如
BootStrap、MDB、tailwind
等中,路由都是通过相应的标签来进行页面的跳转并且大部分都是直接进行网页的切换。但在angular
中,通过添加路由出口和路由链接可进行网页中不同页面视图的显示,并且可以实现部分网页的更新而其他页面不变的功能。这里我新建了一个AppRoutingModule
模块,在独立的顶层模块中加载和配置路由器,使它专注于路由功能。
3.从服务器获取数据
-
这里原来我是打算使用
json
文件保存我网站的电影数据并把它模拟成服务器端获取数据,但是由于json
文件不够灵活,没有使用数据库那么方便易用,因此我采用在云服务器上部署后台服务器deployd
结合MongoDB
数据库作为我网站获取电影数据的数据库服务器。 -
由于我需要将该网页部署到
GitHub
中,因此我将之前使用本地数据来模拟从服务器端获取数据就不可行了。所以我将数据库MongoDB
和后台服务程序deployd
部署到云服务器上,以便实现网站与服务器端电影信息的数据交互,实现电影信息的增删查改。
4.网站的部署
- 这里我通过
angular
官网的部署教程将该网站部署到GitHub
页面上去。首先创建一个储存库用于存放本次项目,然后在本次使用angular CLI
命令ng build --output-path docs --base-href /your_project_name/
构建我的项目,最后提交我的更改并进行推送。在GitHub
项目页面上转到设置并将站点配置为从docs
文件夹发布,保存即可实现网站的部署,最后通过网站链接https://<user_name>.github.io/<project_name>/
就能实现访问。 - 但后面由于发现
GitHub
不能通过http
获取数据库中的数据,因此尝试了许多种方法,踩过许多坑后终于在自己的云服务器上部署上了这次做的Project-Movies
网站。
3、遇到的问题及解决方案
1.angular
编译报错error NG8002: Can't bind to 'ngModel' since it isn't a known property of 'input'.
-
原因
这是因为缺少
FormsModule
,虽然ngModel
是一个有效的angular
指令,但默认情况下是不可用的。它属于可选模块FormsModule
,我们必须自行添加此模块才能使用该指令。 -
解决方案
在类文件
app.module.ts
中添加import { FormsModule } from '@angular/forms';
,然后在其中的imports
添加FormsModule
即可解决该问题。
2.angular
编译报错Type '{}' is missing the following properties from type 'Movie[]': length, pop, push, concat, and 26 more
-
原因
这里的
Movie[]
是一个列表类型的数据,但是我不小心把该数据改为了字典类型的数据,如下:export const MOVIES: Movie[] = [ { id: 1, name: '复仇者联盟4:终局之战'}, { id: 2, name: '信条'} ]; //错误的写成: export const MOVIES: Movie[] = { { id: 1, name: '复仇者联盟4:终局之战'}, { id: 2, name: '信条'} };
-
解决方案
将
Movie[]
修改为列表类型的数据,如上面的第一种情况。
3.浏览器网页不能从电影列表跳转到电影详情
-
原因
原因
这里是因为路由链接没有很好的包含所需要的跳转的页面视图,具体如下:
<a routerLink="/detail/{{hero.id}}"> <span class="badge">{{hero.id}}</span> {{hero.name}} </a> 错误的写成: <a routerLink="/detail/{{hero.id}}"></a> <span class="badge">{{hero.id}}</span> {{hero.name}}
-
解决方案
将模板文件中包含路由链接的标签
<a>
包含标签<span>
,如上面的第一种情况。
4.从json
文件中读取电影数据时浏览器控制台显示Failed to load resource: the server responded with a status of 404 (Not Found)
-
原因
这里是因为浏览器无法找到我存放于本地的
json
文件的位置,因此才会显示该错误并且无法显示我们电影的信息。 -
解决方案
这个
json
文件的读取函数我主要是根据网上的读取代码进行修改得到的,但是实际上并没有成功实现电影数据的读取,因此我转向了云数据库服务器的搭建,真正实现从服务器端请求电影数据,后续有时间可以再进行相应的尝试。
5.无法从云服务器获取电影相关信息
- 原因
- 最开始我通过
MongoDB Compass
软件可以直接连接云服务器上的数据库,因此我以为可以直接通过http
请求MongoDB
数据库,但实际上发现只是数据库的话只能通过Mongo
命令进行访问。 - 另外一个原因是
$(this.moviesurl)/$(id)
命令会导致在本地发起数据请求来获取该数据但是实际上应该向服务器端发起请求得到数据。
- 最开始我通过
- 解决方案
MongoDB
只是数据库,只能使用Mongo
命令访问该数据库,但是如果要使用http
来访问则需要用到deployd
后台服务程序结合MongoDB
数据库搭建一个后台服务程序提供相应的数据库服务(难怪我在MongoDB
官网找了许久都找不到相应的get、post
等数据库API
)。- 对于第二个问题,我把
$(this.moviesurl)/$(id)
修改为*this*.moviesurl + '/' + *id
*`后即可成功从云服务器获取电影数据。
6.使用命令ng add angular-bootstrap-md
安装时报错Cannot find module '@schematics/angular/utility/config'
-
原因
第一次我没有以管理员身份运行,但是我通过解决Cannot find module '@angular/compiler-cli’文章重新安装了
node_modules
后以管理员身份安装angular-bootstrap-md
仍然报错,这应该是某些模块版本与现有模块不兼容导致的。 -
解决方案
由于命令
ng add angular-bootstrap-md
实际上是在app.module.ts
文件导入MDBBootstrapModule
模块文件并在项目根目录下angular.json
文件中添加相关配置,因此我更改为如下两个步骤:Step A:在app.module.ts文件导入MDBBootstrapModule模块文件,如下所示: import { NgModule } from '@angular/core'; import { MDBBootstrapModule } from 'angular-bootstrap-md'; @NgModule({ imports: [ MDBBootstrapModule.forRoot() ] }); Step B:在项目根目录下angular.json文件中添加如下配置: "styles": [ "node_modules/font-awesome/scss/font-awesome.scss", "node_modules/angular-bootstrap-md/scss/bootstrap/bootstrap.scss", "node_modules/angular-bootstrap-md/scss/mdb-free.scss", "src/styles.scss" ], "scripts": [ "node_modules/chart.js/dist/Chart.js", "node_modules/hammerjs/hammer.min.js" ],
7.angular
报错Can't bind to 'ngModel' since it isn't a known property of 'input'
-
原因
这是因为
ngModel
属于表单控件,因此需要先引入表单模块。参考:Angular报错-Can’t bind to ‘ngModel’ since it isn’t a known property of ‘input’
-
解决方案
在
app.module.ts
中添加import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ ..., FormsModule, ], })
8.angular
在浏览器端运行,浏览器控制台报错TypeError: Cannot read property 'xxxx' of undefined
-
原因
这是因为调用该方法或函数的字符串、数组或数组为空,导致变量没有定义,在我的网页中时因为点击某个电影后将会向服务器获取电影信息,同时会显示该电影的详细信息,当电影信息还未传输回来时就显示电影信息时则会报该错误。
-
解决方案
由于请求数据库时不能立即获得数据,所以需要添加
<div *ngIf="movie"></div>
来判断电影信息是否成功获取,若未成功获取则不显示;否则就显示相应的信息。
9.angular
中使用MDB
模块部分图标不能正常显示
-
原因
这是因为
MDB
升级为5.0
后所用标签不兼容以前版本,因此使用功以前版本MDB
代码不能成功运行,出现了部分显示而部分不能正常显示的情况。 -
解决方案
我根据MDB官网提供的组件示例代码修改老版本不兼容的代码后成功运行并正常显示网页内容。
10.网站部署到GitHub
上后不能正常显示
-
原因
这是因为云服务器端的数据库采用的是
http
方式而GitHub
采用的是https
方式进行通信,因此会造成数据交换时出错,因而无法正常显示。 -
解决方案
-
升级
https
协议首先我尝试的是添加服务器的
SLL
证书,使其支持https
协议,但是发现数据库deployd
请求只能使用http
请求,因此即使升级成https
协议也不能正常访问。 -
nginx
代理向老师询问后发现可以采用
nginx
代理的方式在云服务器端进行https
到http
的转换,但实际上并未真正实现云数据库数据传输的效果,而是因为之前测试能否进行https
到http
转换时留下的数据缓存,因此换成其他同学的话就无法获取数据库中的数据 -
使用其他代码托管网站或直接在云服务器上运行
angular
项目发现以上两种方法不行后我也去找了其他能支持
http
协议的网页托管平台,但是发现没有比较适合我的平台,因此我看能不能直接在我自己的云服务器上运行,再通过公网进行网站的访问,但是实际操作中发现不能给angular
指定运行的ip
地址,因此这个想法也不行。 -
手动在云服务器上部署网站
最后由于许多方法都无法解决,我就自己搭建了一个网页服务器用于托管我这次的网页,最终成功的部署于我的云服务器上,也实现了数据库的正常交互,这才真正实现了动态网站的增删查改功能,实现了网站的成功部署。
-
4、总结
- 这次课程结业任务我选用的是前端框架
angular
进行应用网站的搭建,实现了CRUD
即增删查改的功能并具有一定的样式,在整个搭建过程中,我对于angular
框架的理解比上课时老师讲解的内容要更加深入,同时通过搭建云服务器实现网页和云端数据的交互,也更加拓宽了我的视野。整个网站的搭建过程持续了数周时间,在学习的过程中逐渐应用,通过该框架制作出来了这个动态网站。虽然该网站看着十分简单,但遇到的问题绝不止上面列出的部分问题,还有许多的问题没有列出,也正是踩了这些坑,才让我对于angular
框架的理解更加深入和熟悉。 - 这学期的课程先是学习前端相关的知识,包括构建广泛使用的Web程序的三剑客:
HTML
、CSSS
和JavaScript
。然后学习了CSS
前端框架MDBootStrap
搭建静态网站并针对JavaScript
的超集TypeScript
进行学习,最后学习前端框架angular
搭建动态网站。通过整个课程的学习,让我了解了前端开发所需要具备的相关知识,为我们以后深入该领域的发展打下了坚实的基础。