構建一個混合的費用跟蹤應用程序

KatiaZimmer 8年前發布 | 17K 次閱讀 REST Cloudant 移動開發 Ionic Framework

在構建 REST 應用程序時,如果使用某個工具來實現 API 組成和數據連接,可以提高您的工作效率。通過這種方式,您可以將更多的精力集中在應用程序的業務邏輯和用戶體驗上。

在本教程中,您將構建一個工作應用程序來了解如何使用來自 StrongLoop(IBM?的一家子公司)的 API 開發工具。借助開源 LoopBack 框架(該框架構建于 Node.js 之上),您可以輕松地以可視方式開發可擴展的 REST API 并連接到該應用程序所需的數據。 StrongLoop Arc 對 StrongLoop slc 命令行工具進行了補充,包括用于構建、分析和監測 Node.js 應用程序的工具。

您的練習是構建一個簡單的混合費用跟蹤應用程序,該應用程序使用了您用 StrongLoop 開發的 REST API。該 REST API 使用了 Bluemix 中的 Cloudant NoSQL DB 服務來實現數據集成。您將在本地創建一個服務器應用程序來公開 REST API。為了開發混合應用程序的客戶端,可以使用 LoopBack Angular JavaScript SDK(LoopBack 包含的幾個軟件開發工具中的一個)和 Ionic 框架。作為最后一步,我們會將應用程序的服務器端代碼部署到 Bluemix。

如果費用超出了規定的限制,您還可以使用 LoopBack 框架擴展 ExpenseTracker 來發送推送通知 —這方面的練習超出了本教程的討論范圍。

借助 ExpenseTracker 應用程序,用戶可以按照類別記錄自己的日常開銷。客戶端會生成一個費用報告,并以圖表的形式提供該報告。您可以擴展 API,以便客戶端可以根據特定類別或月份來顯示圖表。

構建您的應用程序需要做的準備工作

運行服務器應用程序

獲取代碼

“ 借助開源 LoopBack 框架,您可以輕松地以可視方式開發可擴展的 REST API 并連接到該應用程序所需的數據。 ”

第 1 步 . 創建 Bluemix 應用程序

  1. 登錄到 Bluemix。
  2. 單擊 CREATE APP
  3. 選擇 WEB 作為應用程序類型。
  4. 選擇 SDK for Node.js
  5. 單擊 CONTINUE
  6. 輸入帶有附加的唯一標識符(比如您的用戶名或日期)的 ExpenseTracker 。(如果您嘗試使用的名稱是不可用的,Bluemix 會告訴您。)
  7. 單擊 FINISH

將 Cloudant NoSQL DB 服務綁定到您的應用程序

  1. 在載入您的應用程序后,返回到 Bluemix 儀表板并單擊應用程序名稱轉到應用程序的概述頁面。
  2. 單擊 ADD A SERVICE OR API 按鈕。
  3. 在目錄的 Data and Analytics 部分,選擇 Cloudant NoSQL DB
  4. 單擊 CREATE 將 Cloudant 服務添加到應用程序。
  5. 在提示時重新載入應用程序。
  6. 返回到應用程序的概述頁面,確認 Cloudant NoSQL DB 服務現在已綁定到應用程序。

為 ExpenseTracker 應用程序創建數據庫

  1. 在應用程序的概述頁面上,單擊 Cloudant NoSQL DB 服務來顯示相關細節。
  2. 單擊 LAUNCH 按鈕來啟動 Cloudant NoSQL Database 儀表板。
  3. 單擊右上方的 Create Database 鏈接。在提示您輸入一個數據庫名稱時,輸入 expense-tracker 并單擊 Create

第 2 步 . 在本地開發環境中實現服務器端

在這一步中,將實現一個服務器端應用程序,該應用程序使用 LoopBack 框架來公開 REST API,以便添加費用信息。

創建一個新的服務器端應用程序

  1. 在 OS 命令行下,在您想要放置新應用程序的目錄中,鍵入 slc loopback 并按下 Enter。
  2. 鍵入 ExpenseTracker 作為應用程序名稱并按下 Enter。
  3. 按下 Enter 接受項目目錄的默認名稱 (ExpenseTracker)。

服務器端代碼是在 ExpenseTracker/server 文件夾中生成的。

閱讀: 項目布局引用

閱讀: StrongLoop API 文檔

將 Cloudant 連接器添加到應用程序

ExpenseTracker 應用程序使用 Cloudant NoSQL DB 來實現數據存儲。因為 Cloudant 是 CouchDB 的衍生物,所以您可以將 LoopBack CouchDB 連接器用于應用程序:

  1. 在您的 OS 命令行下,轉到 ExpenseTracker 目錄。
  2. 運行以下命令來安裝 LoopBack Couch 連接器:

    npm install loopback-connector-couch

閱讀: loopback-connector-couch

添加 Cloudant 作為應用程序的數據庫

配置 ExpenseTracker 應用程序,以便連接到您在第 1 步中在 Bluemix 中創建的 Cloudant NoSQL DB 服務:

  1. 在 Bluemix 中的您的費用跟蹤應用程序的概述頁面中,單擊 Cloudant NoSQL DB 服務中的 Show Credentials
  2. 還可以通過 StrongLoop 命令行工具或 Arc Composer 添加您的 Cloudant 憑證。

    在文本編輯器中,打開本地項目的 server/datasources.json 文件并添加 Cloudant 數據庫的詳細信息:
    "cloudant": { 
      "host": "yourhost-bluemix.cloudant.com", 
      "port": 443, 
      "url": "https://yourhost-bluemix.cloudant.com", 
      "name": "cloudant", 
      "connector": "couch", 
      "db": "expense-tracker", 
      "protocol": "https", 
      "auth": { 
        "admin": { 
          "username": "cloudant-admin-username", 
          "password": "cloudant-admin-password"
        }, 
        "reader": { 
          "username": "cloudant-reader-username", 
          "password": "cloudant-reader-password"
        }, 
        "writer": { 
          "username": "cloudant-writer-username", 
          "password": "cloudant-writer-password"
        } 
      } 
     }

設置應用程序數據模型

ExpenseTracker 應用程序使用了一個簡單的數據模型。LoopBack 框架中的數據模型配置還可以公開 REST API:

  1. 在您的 OS 命令行下,轉換到 ExpenseTracker 目錄并輸入:

    slc loopback:model

  2. 提供以下詳細信息來響應提示:
    • 模型名稱: expense
    • 要附加的數據源: cloudant
    • 模型基類: PersistedModel
    • 公開為 REST API: Yes
    • 復數形式: expenses
  3. 按下 Enter 鍵退出模型創建過程。

現在,設置模型屬性( category 、 item 、 price 和 expensedate ):

  1. 對于每個屬性,運行 slc loopback:property 命令并在提示時提供該屬性的詳細信息:
    屬性 模型 屬性名稱 屬性類型 是否是必需的
    category expense category string yes
    item expense item string yes
    price expense price number yes
    expensedate expense expensedate date yes

另外,您還可以使用 Arc Composer 添加屬性。

與數據進行交互

LoopBack 框架會自動為您的數據模型的所有對象生成 REST 端點。它還會相應地生成 Swagger API 文檔,為您提供連接到您的數據的便捷接口。

  1. 在您的 OS 命令行下,轉換到 ExpenseTracker 目錄。
  2. 運行 node 命令來啟動 ExpenseTracker 應用程序。
  3. 在瀏覽器中,訪問 http://localhost:3000/explorer,在 StrongLoop API Explorer 中打開 ExpenseTracker 應用程序的 Swagger API 文檔:

    構建一個混合的費用跟蹤應用程序

  4. 單擊 List Operations 顯示所有可能的操作,這些操作被公開為 REST 方法。通過使用 API Explorer,您可以與模型進行交互并測試服務。

擴展模型交互

您可以通過修改應用程序的 common/models 文件夾中的 expense.js 文件來擴展模型實現。默認文件內容包括:

module.exports = function(Expense) {};

為了使得 ExpenseTracker 根據類別或月份來檢索費用成為可能,可以通過添加一個方法并將該模型模型公開為要使用的客戶端的 REST API 來定制模型。在文本編輯器中,打開 common/models/expense.js 文件,并使用下面的代碼替換其內容:

module.exports = function(Expense) { 
 //Method to get the category based expenses for the month. 
 Expense.getMonthlyCategoryBasedAnalysis = function(cb) 
 { 
    ONE_MONTH = 30 * 24 * 60 * 60 * 1000;  // Month in milliseconds 
    var lastDate = new Date(Date.now() - ONE_MONTH); 
    var result = ""; 
    var jsonArr = []; 
    Expense.find( { expensedate: {gt: lastDate} }, 
    function (err, instance) 
    { 
        var tempArr = [0, 0, 0, 0]; 
        for (var i=0;i<instance.length;i++) 
        { 
            if(instance[i].expensedate > lastDate) 
            { 
                if(instance[i].category == "Food") 
                    tempArr[0] = tempArr[0] + instance[i].price; 
                else if (instance[i].category == "Travel") 
                    tempArr[1] = tempArr[1] + instance[i].price; 
                else if (instance[i].category == "Education") 
                    tempArr[2] = tempArr[2] + instance[i].price; 
                else if (instance[i].category == "Miscellaneous") 
                    tempArr[3] = tempArr[3] + instance[i].price; 
            } 
        } 
        for (var i = 0; i < tempArr.length; i++) { 
            var cat = ""; 
            if(i == 0) cat = "Food"; 
            if(i == 1) cat = "Travel"; 
            if(i == 2) cat = "Education"; 
            if(i == 3) cat = "Miscellaneous"; 
            //create the JSON for the client to consume 
            jsonArr.push({ 
                "category": cat, 
                      "period": "LastMonth", 
                "price": tempArr[i] 
            }); 
        } 
        console.log("out is "+jsonArr); 
        response = jsonArr ; 

      cb(null, response); 
    }); 
 } 
 //Expose the method as a REST API 
 Expense.remoteMethod ('getMonthlyCategoryBasedAnalysis',{ 
      http: {path: '/getMonthlyCategoryBasedAnalysis', verb: 'get'}, 
      //accepts: {arg: 'categoryName', type: 'string', http: { source: 'query' } }, 
      returns: {arg: 'data', type: 'string'} 
    } 
 ); 
 };

上面的代碼使用 find 方法來檢索上一個月的基于類別的費用,然后按類別組織數據。 getMonthlyCategoryBasedAnalysis 被公開為客戶端的一個遠程方法。

閱讀: 遠程方法

第 3 步 . 在您的本地開發環境實現客戶端

您正在構建的混合應用程序對前端使用了 Ionic 框架和 LoopBack 框架的 AngularJS SDK。

閱讀: Ionic 概述

創建 Ionic 應用程序

將客戶端應用程序創建為一個 Ionic 應用程序:

  1. 在您的 OS 命令行下,轉到 ExpenseTracker 目錄,并運行以下命令來下載應用程序模板(您必須處于聯網狀態):

    ionic start client tabs

  2. 在系統詢問您是否覆蓋該文件夾時,選擇 yes。

閱讀: Ionic 項目結構

生成 Angular 服務

閱讀: AngularJS SDK 簡介

LoopBack 框架支持 AngularJS SDK。Ionic 框架使用 Angular 客戶端庫來調用 REST API。要為您的 LoopBack 應用程序生成 Angular 客戶端庫,可以使用 LoopBack Angular 命令行工具:

  1. 轉換到 ExpenseTracker/client 目錄。
  2. 運行以下命令:

    lb-ng ../server/server.js www/js/lb-services.js

    在上面的命令中, ../server/server.js 是主要 LoopBack 服務器腳本的相對路徑,而 www/js/lb-services.js

    是該工具生成的文件的名稱和路徑。

  3. 打開 client/www/js/lb-services.js 文件來查看該工具生成的代碼。修改現有的 urlBase 變量,以便可以調用客戶端實現(此更改僅適用于本地測試):
    var urlBase = "http://localhost:3000/api";

將 ng-resource 模塊添加到應用程序

將 ng-resource 模塊添加到客戶端應用程序,以便應用程序可以調用 REST API:

  1. 在應用程序的客戶端目錄中,運行以下命令:

    bower install angular-resource

    如果被詢問,請選擇最新的版本。該命令會將所需的庫添加到 client/www/lib 文件夾。(此外,您可以從某個 AngularJS 版本

    下載該庫。

  2. 在 <head> 部分,將與 angular-resource

    相關的 JavaScript 添加到 client/www/index.html 文件:

    &lt;script src=&quot;lib/angular-resource/angular-resource.js&quot;&gt;&lt;/script&gt;

實現費用輸入

應用程序需要基于表單的輸入來調用 REST API,讓用戶可以輸入費用。在 controller.js、app.js 和 index.html 模板中執行以下更改:

  1. 修改 client/www/js/app.js 中的模塊聲明,使之包含 lbservices.js 文件,通過將以下代碼行
    angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
    更改為:
    angular.module('starter', ['lbServices','ionic', 'starter.controllers'])
  2. 在 client/www/js/app.js 中,將以 .config(function($stateProvider, $urlRouterProvider) 開頭的數據塊更改為:
    .config(function($stateProvider, $urlRouterProvider) { 
      $stateProvider 
        .state('tab', { 
        url: '/tab', 
        abstract: true, 
        templateUrl: 'templates/tabs.html'
      }) 
      .state('tab.addexpense', { 
        url: '/addexpense', 
        views: { 
          'tab-addexpense': { 
            templateUrl: 'templates/tab-addexpense.html', 
            controller: 'ExpenseController'
          } 
        } 
      }) 
     //This is required for the below step to display charts 
      .state('tab.charts', { 
        url: '/charts', 
        views: { 
          'tab-charts': { 
            templateUrl: 'templates/tab-charts.html', 
            controller: 'ExpenseController'
          } 
    
        } 
      }); 
    
      // if none of the above states are matched, use this as the fallback 
      $urlRouterProvider.otherwise('/tab/addexpense'); 
     });
  3. 打開 client/www/templates/tabs.html 文件,并將 Dashboard 選項卡的 <ion-tab> 修改為:
    <!-- Add Expense Tab--><ion-tab title="Add Expense" icon-off="ion-ios-plus-outline" 
     icon-on="ion-ios-plus" href="#/tab/addexpense"> 
     <ion-nav-view name="tab-addexpense"></ion-nav-view> </ion-tab>
  4. 將 client/www/templates/tab-dash.html 文件的名稱更改為 tab-addexpense.html。使用以下代碼替換文件內容:
    <ion-view view-title="Add Expense"> 
      <ion-content padding="true" class="has-header" scroll="false" overflow-scroll="false"> 
        <div> 
          <br> 
          <form name="expensesForm" ng-submit="addExpense()"> 
          <div class="list"> 
            <label class="item item-input"> 
              <span class="input-label">Category</span> 
              <select class="form-control focus" 
                  name="category" required ng-model="newExpense.category"> 
                  <option name="Food" id="Food">Food</option> 
                  <option name="Travel" id="Travel">Travel</option> 
                  <option name="Miscellaneous" id="Cosmetics">Miscellaneous</option> 
                  <option name="Education" id="Education">Education</option> 
                </select> 
            </label> 
            <label class="item item-input"> 
              <span class="input-label">Item</span> 
                  <input type="text" class="form-control" name="item" placeholder="Expense Item Name" 
                      autocomplete="off" required ng-model="newExpense.item"> 
            </label> 
            <label class="item item-input"> 
              <span class="input-label">Price</span> 
                  <input type="text" class="form-control" name="price" placeholder="Expense Price" 
                      autocomplete="off" required ng-model="newExpense.price"> 
                   <input type="hidden" class="form-control" name="date" placeholder="Date" 
                       autocomplete="off" required ng-model="newExpense.expensedate"> 
           </label> 
         </div> 
               <br> 
           <button class="btn btn-default" ng-disabled="expensesForm.$invalid">Add Expense</button> 
         </form> 
       </div> 
     </ion-content> 
     </ion-view>
  5. 將 Add Expense REST API 調用添加到 client/www/js/controllers.js 文件。此外,將 ExpenseController 添加到控制器:
    .controller('ExpenseController', 
             [ '$scope','$rootScope', 'Expense', function($scope, $rootScope, Expense) { 
        $scope.newExpense = {}; 
        $scope.newExpense.category = 'Food'; 
        $scope.newExpense.expensedate = new Date(); 
        //Method call to create the expense record 
        $scope.addExpense = function() 
        { 
            Expense.create($scope.newExpense).$promise.then(function(expense) 
            { 
                $scope.newExpense = {}; 
                $scope.newExpense.category = 'Food'; 
    
            }); 
        }; 
     }])

將定制的 REST API 添加到 lb-services.js

對于要使用您在第 2 步中添加的定制 REST API 的應用程序,必須修改 lb-services.js 文件:

  1. 打開 client/www/js/lb-services.js。
  2. 搜索 findOne 方法聲明,該聲明位于 Expense 模型聲明之下。
  3. 在緊接著 findOne 方法的后面,為第 2 步中在 expense.js 文件中聲明的定制方法添加以下代碼:
    "getMonthlyCategoryBasedAnalysis": { 
         url: urlBase + "/expenses/getMonthlyCategoryBasedAnalysis", 
         method: "GET"
       },

將 angular-chart 模塊添加到應用程序

要在應用程序中顯示基于類別的每月費用圖表,可添加 angular-chart 模塊:

  1. 在您的 OS 命令行下,轉到客戶端目錄。
  2. 要在 client/www/lib 文件夾中包含所需的庫,可以運行以下命令:

    bower install angular-chart.js

    此外,您還可以從 項目站點

    下載該庫。

  3. 在 <head> 部分,將 Angular SDK 添加到 client/www/index.html 文件:
    <script src="js/lb-services.js"></script>
  4. 在 <head> 部分,將與 angular-chart 相關的 JavaScript 添加到 client/www/index.html 文件:
    <script src="lib/Chart.js/Chart.min.js"></script> 
     <script src="lib/angular-chart.js/dist/angular-chart.js"></script>
  5. 在 <head> 部分,將與 angular-chart 相關的 CSS 代碼添加到 index.html 文件:
    <link rel="stylesheet" href="lib/angular-chart.js/dist/angular-chart.css">
  6. 通過將 chart.js 添加到模塊聲明,將 chart 模塊添加到應用程序:
    angular.module('starter', ['lbServices','ionic', 'chart.js','starter.controllers'])
  7. 將 chart.js 添加到 controllers.js 的第一行:
    angular.module('starter.controllers', ['chart.js'])

添加一個基于類別的每月費用表

要檢索基于類別的每月費用,必須調用 getMonthlyCategoryBasedAnalysis 方法:

  1. 打開 client/www/templates/tabs.html 文件并將 Chats 選項卡的 <ion-tab> 更改為:
    <!-- Charts Tab --> 
     <ion-tab title="Charts" icon-off="ion-load-d" icon-on="ion-load-b" href="#/tab/charts"> 
        <ion-nav-view name="tab-charts"></ion-nav-view> 
     </ion-tab>
  2. 刪除或注釋掉 client/www/templates/tabs.html 文件中的 Account 選項卡。
  3. 將 client/www/templates/tab-chats.html 重命名為 tab-charts.html。
  4. 將以下代碼添加到 tab-charts.html 文件:
    <ion-view view-title="Charts" ng-init="drawCategoryMonthlyChart()"> 
      <ion-content> 
            <canvas id="bar" class="chart chart-bar" chart-data="data" chart-series="series" 
                chart-labels="labels" responsive="false" height="100" chart-legend="true" 
                chart-options="{datasetFill: false, scaleBeginAtZero : false}"> 
            </canvas> 
      </ion-content> 
     </ion-view>
  5. 將以下代碼添加到 client/www/js/controllers.js 文件,作為 ExpenseController 控制器的一部分:
    //Method call to draw the chart. Calls the REST API & forms the angular chart based variables. 
      $scope.drawCategoryMonthlyChart = function() 
        { 
            Expense.getMonthlyCategoryBasedAnalysis().$promise.then(function(results) 
            { 
                      expenseData = results.data; 
                var foodPrice = 0, travelPrice = 0, eduPrice = 0, miscPrice = 0; 
                for(i=0;i<4;i++) 
                { 
                     if(expenseData[i].category == "Food") 
                         foodPrice = expenseData[i].price; 
                                 if(expenseData[i].category == "Travel") 
                        travelPrice = expenseData[i].price; 
                                 if(expenseData[i].category == "Education") 
                        eduPrice = expenseData[i].price; 
                                if(expenseData[i].category == "Miscellaneous") 
                        miscPrice = expenseData[i].price; 
                } 
    
    
            $rootScope.labels = ['Food','Travel','Education','Miscellaneous']; 
            $rootScope.series = ['ThisMonth']; 
               $rootScope.data = [ 
                  [foodPrice, travelPrice, eduPrice, miscPrice] 
                   ]; 
              }) 
        };

第 4 步 . 將應用程序推送到 Bluemix

將服務器應用程序推送到 Bluemix,以便客戶端可以調用 REST API:

  1. 可選:為了減少您上傳到 Bluemix 的代碼量,請將客戶端文件夾移動到不同的地方,并(在您進行到第 5 步時)從新的位置運行客戶端應用程序。
  2. 在您的 OS 命令行下,轉到 ExpenseTracker 目錄并運行以下代碼:

    cf push ExpenseTracker -c &quot;node server/server.js&quot;

  3. 轉到 http:// app-name .mybluemix.net/explorer(其中的 app-name 是您在第 1 步中在 Bluemix 中創建的 Node.js expense-tracker 應用程序的名稱)來檢查正在運行的 REST API。

第 5 步 . 運行客戶端混合應用程序

因為客戶端應用程序是一個混合應用程序,所以它可以在一個瀏覽器、模擬器或移動設備中運行。這一節將介紹如何在一個瀏覽器或 iOS 設備中運行它。

在瀏覽器中測試應用程序

  1. 在 client/www/js/lb-services.js 文件中,更改 urlBase ,使之指向 Bluemix 路由: http://app-name.mybluemix.net/api 。
  2. 在您的 OS 命令行下,更改到 ExpenseTracker/client 目錄并運行以下代碼:

    ionic serve

  3. 在您的瀏覽器中,轉換到 http://localhost:8100/。單擊 Add Expense 來測試用于添加費用的表單:
  4. 單擊 Charts 來查看費用報告:

在 iOS 設備中測試應用程序(可選)

  1. 在您的 OS 命令行下,轉換到應用程序的客戶端文件夾并運行以下代碼:

    ionic platform add ios

    此命令將向客戶端應用程序添加 iOS 平臺支持。 (類似地, ionic platform add android

    將向客戶端應用程序添加 Android 平臺支持。)

  2. 運行 ionic build ios 來構建針對 iOS 設備的項目。
  3. 上面的命令創建了一個名為 client/platforms/ios 的文件夾,該文件夾包含一個 Xcode 項目。在您的 Xcode 工具中打開該項目。通過 USB 連接您的設備,并選擇要運行該項目的設備:
  4. 測試用于添加費用和查看費用圖表的應用程序界面:

閱讀: 測試您的 Ionic 應用程序

備注:您的應用程序需要能夠訪問 HTTP 傳輸,因為它要調用 REST API。您可能會得到消息 App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure 。您可以通過添加以下代碼,通過應用程序的 client/platforms/ios/client/Info.plist 文件處理臨時異常:

<key>NSAppTransportSecurity</key> 
  <dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <true/>  </dict>

閱讀: NSAppTransportSecurity

結束語

通過使用 StrongLoop LoopBack 框架和 Ionic 框架來開發示例應用程序,您現在知道了(使用正確的工具)公開 REST API 并在混合應用程序使用它們是多么容易。您可以擴展在本教程中學到的知識,通過定義模型之間的關系,創建生產就緒的、企業級的應用程序。

BLUEMIX SERVICE USED IN THIS TUTORIAL: Cloudant NoSQL DB 提供了對始終打開的完全托管 NoSQL JSON 數據層的訪問。

相關主題: 移動開發 Node.js

來自: http://www.ibm.com/developerworks/cn/mobile/mo-build-a-hybrid-app-strongloop-bluemix-trs/index.html?ca=drs-

 本文由用戶 KatiaZimmer 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!