《全棧開發之道》MEAN學習筆記-簡單的商品管理功能
本文介紹了利用MEAN技術棧(MongoDB,Express,Angular,Node.js)構建一個簡單的商品管理功能
所需環境:Node.js、MongoDB 、(git)
先建立一個基於EJS的Express工程
express --view=ejs myvideo
cd myvideo
npm install
由於之後我們會用monk來實現伺服器與資料庫 的互動,我們先安裝monk
npm install monk --save
然後我們先建立需要的資料夾及檔案
- 進入public資料夾,建立partials資料夾,並在其中建立home.html和video-form.html.
- 然後進入public資料夾中的javascripts資料夾,並在其中建立vidzy.js作為應用伺服器
- 最後,我們進入myvideo資料夾中的routes資料夾,並在其中建立videos.js作為控制器
準備工作完成,現在開始編寫程式碼。
我們先來構建angular頁面檔案,進入views資料夾,開啟index.js
<!DOCTYPE html>
<!-- 讓 html 元素成為 AngularJS 應用的根元素。其中Vidzy是模組的名字,之後我們會在vidzy.js即控制器中建立 -->
<html ng-app='Vidzy' >
<head>
<!-- 新增bootstrap和angular框架 -->
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css' />
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular-resource.min.js"></script>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular-route.min.js"></script>
<script src= "/javascripts/vidzy.js" > </script>
</head>
<body>
<!--使用 ngView 指令, 該 div 內的 HTML 內容會根據路由的變化而變化 -->
<div ng-view> </div>
</body>
</html>
接下來我們來編寫用於替換 <div ng-view> </div>的兩個頁面
先編寫home.html,該頁面用於首頁,至於如何使其出現在首頁,將會在之後的路由中設定。
<h1>Home Page</h1>
<p>
<!-- 加#是為了相容舊瀏覽器 -->
<a href="/#/add-video">Add a Video</a>
</p>
<ul>
<!-- ng-repeat與迴圈遍歷有點相似,此處的意思為依次呈現出videos陣列中的所有video的title屬性 -->
<li ng-repeat='video in videos'>{{video.title}}</li>
</ul>
接下來,我們將video-form.html也編寫好。
<h1>Add a Video</h1>
<form >
<div class ="form-group">
<label>Title</label>
<!-- ng-model將會繫結輸入框的值到 scope 變數中,此處的程式碼會使輸入框的值與控制器檔案中的$scope.videos陣列中的一個video的title屬性繫結 -->
<input class="form-control" ng-model="video.title" >
</div>
<div class="form-group" >
<label>Description</label>
<textarea class="form-control" ng-model="video.description" > </textarea>
</div>
<!-- ng-click指令,當點選這個按鈕時會觸發控制器中的save()方法 -->
<input type="button" class="btn btn-primary" value="Save" ng-click="save()" >
</form>
編寫好用於顯示的angular頁面之後,
我們先來編寫vidzy.js即控制器
//控制器
// 此處直接呼叫全域性變數angular來建立Vidzy模組,並添加了兩個依賴模組
//ngResource模組提供了'$resource'模組,$resource模組是基於$http的一個封裝
//ngRoute是路由模組,提供了$routeProvider模組用於設定路由
var app = angular.module('Vidzy', ['ngResource','ngRoute']);
//設定路由
app.config(['$routeProvider', function($routeProvider)
{
$routeProvider
//此處意為訪問首頁即http://localhost:3000/ 時會用home.html中的內容來替換index.ejs中設定了ng-view的div元素,
//並且呼叫名為'HomeCtrl'的控制器,將在下面的程式碼編寫控制器
.when('/',
{
templateUrl: 'partials/home.html',
controller: 'HomeCtrl'
})
.when('/add-video', {
templateUrl: 'partials/video-form.html',
controller: 'AddVideoCtrl'
})
//此處意為沒有匹配的路由時,將會預設跳轉到'/'路徑
.otherwise({
redirectTo: '/'
});
}]);
//建立HomeCtrl控制器
app.controller('HomeCtrl', ['$scope','$resource',function ($scope, $resource) {
var Videos = $resource('/api/videos');//此處可以將Videos物件理解為vidzy.js控制器與videos.js伺服器互動的介面
//query方法屬於GET型別請求
Videos.query(function(videos)
{
//將videos.js伺服器返回的videos物件陣列賦值給$scope.videos,這樣home.html中的列表便能依次顯示這個物件陣列中的每一個物件了
$scope.videos = videos;
});
}]
);
//建立AddVideoCtrl控制器
app.controller('AddVideoCtrl', ['$scope', '$resource', '$location',
function($scope, $resource, $location)
{
//建立$scope.save方法,與video-form.html中按鈕ng-click="save()"的save方法對應
$scope.save = function()
{
var Videos = $resource('/api/videos');
//$resource的save方法屬於POST型別,此處將video-form.html中表單裡填寫的內容POST給伺服器
Videos.save($scope.video, function()
{
//post成功後,呼叫回撥函式,跳轉到首頁
$location.path('/');
});
};
}]);
最後我們 來編寫videos.js
//伺服器
var express = require('express');
var router = express.Router();
var monk = require('monk');
//var db = monk('localhost:27017/vidzy');
var db = monk('localhost:27017/myVideoDB');
//處理get請求,本案例中與vidzy.js控制器中的query方法對應
router.get('/', function(req, res)
{
//從資料庫中讀取資料並返回給控制器
var collection = db.get('videos');
collection.find({}, function(err, videos)
{
if (err) throw err;
res.json(videos);
});
});
// 增加一件商品
//處理post請求,本案例中與vidzy.js控制器中的save方法對應
router.post('/', function(req, res)
{
console.log ( req.body );
//將控制器post請求中的資料插入資料庫中,並返回插入後的資料
var collection = db.get('videos');
collection.insert(
{
title: req.body.title,
description: req.body.description
}, function(err, video)
{
if (err) throw err;
res.json(video);
});
});
module.exports = router;
別忘記在app.js中插入以下程式碼,因為之前我們在$resource()中寫入的路徑為/api/videos
app.use('/api/videos', require('./routes/videos'));
啟動工程
npm start
最後我們來理一下思路
啟動工程之後,我們輸入http://localhost:3000/就會顯示home.html中的內容,這是因為我們設定了路由。
如果資料庫中有資料,我們便會看到一條條商品記錄,這是因為控制器向伺服器傳送了GET請求,伺服器從資料庫中取出資料並返回響應給控制器
點選Add a Video我們進入到video-form.html頁面,輸入資料之後點選按鈕,控制器便會發送POST請求(輸入的資料包含在請求中)給伺服器,伺服器接收請求,並將請求中的資料插入資料庫,然後呼叫回撥函式,返回響應(包含輸入資料後的商品資料即更新後的商品資料)給控制器,控制器接收響應,並呼叫回撥函式跳轉到home.html頁面
第一次寫部落格,MEAN技術棧也是最近開始學習,之後會總結一些RESTful API和與angular無關的伺服器端程式碼,因為之後我會去學習react而不是angular。
若有謬誤或紕漏,請大佬指正,也歡迎大家與我交流web開發的相關知識