1. 程式人生 > >《全棧開發之道》MEAN學習筆記-簡單的商品管理功能

《全棧開發之道》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開發的相關知識