1. 程式人生 > >基於ngMockE2E實現後臺資料模擬

基於ngMockE2E實現後臺資料模擬

   引言

   今天老大給了新任務,在開始給我說的時候讓我改造一個指引,上面的流程是比較簡單的,所以在開始的時候

沒有當回事,因為對這些東西比較熟悉了,但是在說完需求以後告訴我這個專案不建立後臺,所有的流程操作都在前

臺完成,這一下子就整懵逼了,沒有後臺數據怎麼辦,那些流程的流轉咋弄,結果老大說資料只需要模擬一份就可以

了,不需要入庫,但是上面的什麼流程啟動,傳送,儲存功能都需要實現。

  在網上找了一些基於angular模擬後臺資料的方法,最終確定用ngMockE2E來實現,關於ngMockE2E的說明是這樣

的:

  The ngMockE2E is an angular module which contains mocks suitable for end-to-end testing. Currently there is only one mock present in this module - the e2e $httpBackend mock.

  其實ngMockE2E的工作原理這樣的:如果我們在module中引入了ngMockE2E這個模組,頁面中的所有的請求則不會

真正的請求到後臺,而是被其中的$httpBackend攔截,$httpBackend會提供相應的get、post、put、delte請求,一

旦請求地址和提供的地址想匹配則執行相應的方法。

  簡單總結一下這麼做的好處:

  1、如果你並不是介面api的開發者,使用mock資料你就不用等待介面api設計完成就可以開始本地開發


  2、如果你自己開發介面的api,使用mock資料不僅可以讓你更專注於前端開發,還不比糾結於後端具體的細節實
 

  3、你可以快速的開發內容而不用管後臺邏輯


  4、建立mock服務還可以幫助你設計介面api的結構


  5、mock資料服務還可以給其他angular元件在對應服務上做單元測試用

  下面開始我們的Demo:

   我們需要在html(index.html)頁面引入2個檔案 angular.js angular-mocks.js

<span style="font-size:18px;"><span style="font-size:18px;"><!DOCTYPE html>
<html ng-app="app">

<head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script src="angular.js"></script>
    <!--<script src="angular-resource.js"></script>-->
    <script src="angular-mocks.js"></script>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <!--<link rel="stylesheet" href="style.css" />-->
    <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
<p>All students:</p>
<ul>
    <li ng-repeat="student in students">{{ student.name }}</li>
</ul>

<p>Student1: {{ ada.name }}</p>

</body>

</html></span></span>

 所需要的檔案我已經上傳到csdn,在文章末尾有下載地址;

  下面來看我們的app.js檔案的內容,首先看看我們的module以及依賴的模組

<span style="font-size:18px;"><span style="font-size:18px;">var app = angular.module('app', [
  'ngMockE2E'
]);</span></span>

  下面來完成我們的$httpBackend的定義,它的定義式需要通過一個run模組來完成的,在我們的demo中我們把它添

加到一個run模組中,然後定義一組students

<span style="font-size:18px;"><span style="font-size:18px;">app.run(['$httpBackend', function($httpBackend) {
  students= [
    {
      id: 1,
      name: 'Ada Lovelace',
      phone: '8445551815'
    },
    {
      id: 2,
      name: 'Grace Hopper',
      phone: '8445551906'
    },
    {
      id: 3,
      name: 'Charles Babbage',
      phone: '8445556433'
    }
  ];

  // $httpBackend interactions are defined here...
}]);</span></span>

 這個students陣列是mock backbend所有的操作都可以操作的,就像我們後臺的資料庫一樣,這是我我們建立前臺模擬資料庫的一種方式,另外幾種建立方式讀者自行學習。

 下面我們先簡單的來模擬一個查詢學生的介面,用get方式請求後返回整個學生集合。

<span style="font-size:18px;"><span style="font-size:18px;">// Query; returns all students.
$httpBackend.whenGET('/students').respond(students<span style="font-family: SimSun;">);</span></span></span>

  我們你需要發出一個get請求,請求地址為“/studnets”,則可以接收到所有的學生。
<span style="font-size:18px;"><span style="font-size:18px;">  $http.get("/students").success(function (data) {
        $scope.students= data;
    })
</span></span>

  這樣我們就可以在頁面中迴圈輸出所有的學生的姓名。

  下面我們來實現儲存的方法,也就是想students陣列中增加一條新紀錄,利用post請求攜帶student資料。

<span style="font-size:18px;"><span style="font-size:18px;">// Save; create a new contact.
$httpBackend.whenPOST('/students').respond(function(method, url, data) {
  var newStudent = angular.fromJson(data);
  students.push(newStudent);

  return [200, newStudent, {}];
});</span></span>

  因為angular元件會把資料當作json來處理且不會複查,所以一定要注意將序列化的學生資料轉成json。建立一

條新的紀錄就像在students陣列push一條資料一樣簡單。

  如果我們想要在物件中獲取一條學生記錄就需要做兩件事情:從URL中獲取ID,根據id在陣列中取值。

 $httpBackend.whenGET(/\/students\/(\d+)/, undefined, ['id']).respond(function(method, url, data, headers, params) {
        var student= findStudentById(params.id);

        if (student== null) {
            return [404, undefined, {}];
        }

        return [200, student, {}];
    });

  我們用一個正則匹配url,獲取到id的集合。angular把匹配的到的結果儲存到params的id屬性上,也就是

whenGET方法的第三個入參。再抓去這個值傳到findStudentById方法中,將查詢的結果返回給我們。最後,我們返回

查詢結果,如果為空就返回404。

  下面我們看一下findStudentById的方法的程式碼:

 function findStudentById(id) {
        
        var studentId = Number(id);

        var matches = students.filter(function(student) {
            return student.id === studentId;
        });

        var student = matches.shift();

        return student;
    }

  下面來介紹更新的方法,和get方法是差不多的:

    $httpBackend.whenPUT(/\/students\/(\d+)/, undefined, undefined, ['id']).respond(function(method, url, data, headers, params) {
        var student = findstudentById(params.id),
            parsedData = angular.fromJson(data);

        if (student == null) {
            return [404, undefined, {}];
        }

        angular.extend(student, parsedData);

        return [200, student, {}];
    });

同樣我們根據在URL截獲的id引數在陣列中查詢到對應的資料記錄,然後利用angular.extend方法將資料記

錄更新。

  刪除方法同樣和上面的get或者put方法類似,先根據ID查詢到相應的記錄,然後刪除。

  $httpBackend.whenDELETE(/\/students\/(\d+)/, undefined, ['id']).respond(function(method, url, data, headers, params) {
        var student = findstudentById(params.id);

        if (student == null) {
            return [404, undefined, {}];
        }

        // Replace students array with filtered results, removing deleted student.
        students.splice(students.indexOf(student), 1);

        return [200, undefined, {}];
    });

 通過上面的GET、PUT、DELETE、POST等操作我們已經完成了對後臺的服務的模擬和資料的定義,到這我們的後臺模

擬就已經完成了,下面就是定義我們應用控制器,在這控制器我們將對服務進行呼叫來完成對後臺操作的模擬。

app.controller('MainCtrl', function($scope,$http) {
    var tempData= {
            name: '曉兒',
            phone: '1221212212',
            sex:'男'
        };
        $http.post("/students",tempData).success(function (data) {
            console.log(data);
        })
    $http.put("/students/1",tempData).success(function (data) {
        console.log(data);
    })
    
    $http.delete("/students/2").success(function (data) {
        console.log(data);
    })
    $http.get("/students").success(function (data) {
        $scope.students = data;
    })
});

  在這這個demo中我只是給大家簡單的列印了一下,沒有進行詳細的顯示,但是原理都是比較容易懂得,demo到這

給大家介紹的也差不多了,希望對大家有幫助。 

  再這在給大家介紹一個在上面demo中沒有寫的一個用法,就是API文件中提到的passThrough關鍵字,看一下這個

東西的基本用法:

     $httpBackend.whenGET(/\/views\//, undefined, undefined).passThrough();

  很多時候我們會遇到請求頁面地址的問題,但是我們並不希望在這個請求被攔截,讓頁面的渲染被阻止,也不需

要返回資料,這就需要我們的passThrough,像上面那樣符合請求地址的,則不進行阻攔。

  PS:demo下載地址:點我下載