豆瓣电影列表项目说明
使用 AngularJS + Bootstrap + Node.js 构建的一个电影列表展示单页应用
启动项目
1 | $ nodemon add.js |
或者:
1 | $ node add.js |
豆瓣开发接口 API
- 所有的接口地址都是以:http://api.douban.com/v2 开头的
- 正在热映 http://api.douban.com/v2/movie/in_theaters
- 即将上映 http://api.douban.com/v2/movie/coming_soon
- top250 http://api.douban.com/v2/movie/top250
- search http://api.douban.com/v2/movie/search?q={text}
- 电影条目接口: http://api.douban.com/v2/movie/subject/:id
项目骨架
- app
- app.js
- app.css
- index.html
- in_theaters
- view.html
- module.js
- coming_soon
- view.html
- module.js
- top250
- view.html
- module.js
- READMO.md
- .gitignore
- .editorconfig
- bower.json
- .bowerrc
页面开发流程:
(一)、构建页面(bootstrap)
选择模板 –> 列表组 –> 媒体组件
模板页面
1 | <!DOCTYPE html> |
(二)、模块划分
中间变化部分每一个对应一个视图: view.html 和 模块 module.js
in-theaters 正在热映视图、正在热映控制器、正在热映对应的模型代码
coming-soon 即将上映视图、即将上映控制器、即将上映对应的模型代码
top250 top250视图、top250控制器、top250模型代码
局部 HTML 发生变化。
路由:
- Node 中的路由:后台接收请求,渲染了了不同的页面。
- 前端路由,当点击一个连接的时候,显示不同的页面,不需要后台,前端也可以渲染,无非前端的路由变成了哈希值了。
主模块:–> view 里放变化的中间的内容:怎么放?怎么加载?点击即将上映,局部 HTML 发生变化。–> 前端路由
1 | <div ng-view class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> |
这回是前端路由,前端的路由变成了 hash 值。
view.html
中放中间变化的内容
1 | <!-- 每页不同部分 --> |
★★★★★★★★★★★★★★★★★★
在 angular 中使用路由,ng 官方提供了一个 ngRoute 模块。
(1)、视图(v)-页面
1 | <!-- ... --> |
(2). 安装包
1 | $ npm install --save angular |
(3). 在视图页面中引包
1 | <script src="node-modules/angular/angular.js"></script> |
(4). 创建模块
使用 Angular 的依赖模块 ngRoute
1 | // 加载专门处理路由的 ngRoute 模块 |
(5). 控制器作用到视图
a.html 页面需要一个 title
<h2>AngularJS 项目流程</h2>
b.html 页面需要一个src
<img ng-src="" alt="" />
<h4></h4>
c.html 页面需要列表
<li ng-repeat="fruit in fruits track by $index"></li>
(6). 作用到主页面视图-ng-view
1 | <body ng-app="DemoApp"> |
★★★★★★★★★★★★★★★★★★
(三)、模块划分-控制器-路由
通过主模块加载 3 个小模块
主页面: index.html
1 | <!DOCTYPE html> |
主模块: app.js
1 | // 主模块加载其它模块,就可以使用别的模块中的控制器了 |
正在上映模块:/in_theaters/module.js
1 | (function (angular) { |
即将上映模块:/comming_soon/module.js
1 | (function (angular) { |
top250 模块 /top250/module.js
1 | (function (angular) { |
(四)、绑定假数据
主页面视图:static/index.html
1 | <!DOCTYPE html> |
其他模块视图:in_theaters/view.html
1 | <h1 class="page-header">{{ title }}</h1> |
请求 API,将数据绑定到视图预备知识
★★★★★★★★★★★★★★★★★★
ng 中的 $http 请求资源
问题:豆瓣 API 不支持:$htpp.jsonp('http://api.douban.com/v2/movie/in_theaters?count=5&callback=JSON_CALLBACK')。
1 | (function (angular) { |
前后端分离
a) 前后端分离
(1)、V + C 前端 视图 + 控制器
(2)、M 后台 操作数据库
(3)、C 可以实现加载任意 V,在 V 里通过 XMLHttpRequest 发送请求向,索取数据
(4)、C 靠JS、CSS、HTML 是不能实现的
(5)、为了实现 C 前端团队需要依赖于 Nodejs、PHP、Python 等后端语言
(6)、前后端分离可以实现前后端完全解藕,使得后端数据更加稳定统一
(7)、可能会引起跨域问题,解决办法:jsonp
b) 前后端不分离
1) V = 前端 C + M = 后端
暴漏了 static 静态资源,所有的资源都可以直接访问
1 | var express = require('express'), path = require('path'); |
node 不仅仅能作为一个服务器接收请求,还能主动去请求别人的服务器,完全不受跨域影响。让 Node 做一个中转层。
1 | // 使用 node 发送请求 |
request 包
1 | $ npm install --save request |
★★★★★★★★★★★★★★★★★★
(五)、请求 API,将数据绑定到视图
用 node 来请求数据,把项目跑到 node 里面,完全不用考虑跨域,node 做一个中间层,专门来做 UI 渲染。
安装 express
1 | $ npm install express request --save |
Node 中转请求接口 app.js
1 | var express = require('express'); |
主模块 app.js
1 | // 主模块加载其它模块,就可以使用别的模块中的控制器了 |
配置文件路径:
1 | const path = require('path'); |
其它模块 module.js
1 | (function (angular) { |
(六)、通过路由实现简单的分页传参功能
路径中传页码,使用路由提供的 API 更新当前请求路径中的请求参数。
(七)、通过配置路由参数实现多模块重用
ng 中和后台原理相似,都支持路由参数
(八)、利用自定义指令解决导航栏状态切换
在需要操作 DOM 时
(九)、解决详情页搜索问题
总结
整个小项目工作流程
- 前台主模块加载其它模块并设置路由,
- 前台其它模块 module.js 中的 $http 发起请求
- 请求中转 app.js
- 中转 app.js 向后台(豆瓣 API)发起请求
- 再由中转 app.js 将数据响应给前台 module.js
- 前台数据绑定,渲染视图