Node.js開發入門—使用AngularJS內置服務

jopen 9年前發布 | 18K 次閱讀 Node.js Web框架 angularjs


在上一篇,“AngularJS簡單示例”中演示了一個非常簡單的使用Angular的小demo,那篇已經太長,原本要介紹的一些內容只好單另開篇了。這些內容,就是如何使用Angular服務。

我們還是基于“AngularJS簡單示例”中的示例來改造一下。新的示例,能從Node.js+Express構造的服務器上獲取管理菜單。為了實現這個,需要做幾部分改造:

  • 服務器提供adminMenu的下載功能,需要修改app.js,處理路由

    </li>

  • 修改Angular實現的控制器x-controller,使用$http服務從Web服務器下載adminMenu

    </li>

  • 修改HTML模板,觸發下載動作

    </li> </ul>

    修改app.js

    首先要將app.js文件的編碼格式改一下,改成UTF8,因為我在代碼里直接硬寫入了中文。代碼如下:

    var express = require('express');
    var path = require('path');
    var favicon = require('serve-favicon');
    var logger = require('morgan');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');
    
    var routes = require('./routes/index');
    var users = require('./routes/users');
    
    var app = express();
    
    // view engine setup
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'jade');
    
    // uncomment after placing your favicon in /public
    //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
    app.use(logger('dev'));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.use('/', routes);
    app.use('/users', users);
    
    app.get('/adminMenu', function(req, res, next){
      var menus = [
        {
          text: "系統管理",
          enabled: true,
          subMenus:[
            {
              text: "用戶管理",
              enabled: true,
              action:"/admin/addUser"
            },
            {
              text: "角色管理",
              enabled: true,
              action:"/role"        
            },
            {
              text: "權限管理",
              enabled: true,
              action:"/access"        
            }
          ]
        },
        {
          text: "內容管理",
          enabled: false,
          subMenus:[
            {
              text: "直播流監控",
              enabled: true,
              action:"/stream-monitor"
            },
            {
              text: "預約管理",
              enabled: true,
              action:"/book-mgr"        
            }
          ]    
        },
        {
          text: "推送管理",
          enabled: true,
          subMenus:[
            {
              text: "推送列表",
              enabled: true,
              action:"/push-list"
            },
            {
              text: "新增推送",
              enabled: false,
              action:"/add-push"        
            }
          ]    
        }    
      ];
    
      res.status(200).send(menus);  
    });
    
    // catch 404 and forward to error handler
    app.use(function(req, res, next) {
      var err = new Error('Not Found');
      err.status = 404;
      next(err);
    });
    
    // error handlers
    
    // development error handler
    // will print stacktrace
    if (app.get('env') === 'development') {
      app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
          message: err.message,
          error: err
        });
      });
    }
    
    // production error handler
    // no stacktraces leaked to user
    app.use(function(err, req, res, next) {
      res.status(err.status || 500);
      res.render('error', {
        message: err.message,
        error: {}
      });
    });
    
    
    module.exports = app;

    從“app.get(‘/adminMenu’”這行開始,我添加了響應/adminMenu的代碼。同時設置了部分菜單項的enabled屬性,讓從服務器獲取的菜單與“Angular簡單示例”中來自本地的菜單不同。

    觸發下載

    我修改了admin.html文檔,使用了ng-init指令來執行作用域內的init方法。在init方法內,使用$http服務下載管理菜單。

    新的html文件被我重命名為admin2.html,依然放在public目錄下。相比admin.html,admin2.html只改動了兩行代碼:

      <body>
        <div class="x-view-full" ng-controller="x-controller" ng-init="init()">
        ......
        <script src="/javascripts/admin2.js"></script>
      </body>

    ng-init指令允許我們在當前作用域內執行一個JS表達式。

    使用$http服務下載管理菜單

    我修改了admin.js,重名為admin2.js,放在public/javascripts目錄下。admin2.js內容如下:

    angular.module('x-admin', []).
    controller('x-controller', ['$scope', '$http', function ($scope, $http) {
      $scope.currentUser="ZhangSan";
      $scope.content = '/welcome.html';
    
      $scope.menus = [];
    
      $scope.init = function(){
        $http.get("/adminMenu")
             .success(function(data, status, headers, config){
               console.log("got menus");
               $scope.menus = data;
             })
             .error(function(data, status, headers, config){
               console.log("got menus failed. status - " + status);
             });
      };
    
      $scope.setContent = function(action){
        console.log(action);
        $scope.content=action;
      };
    }]);

    我為作用域定義了init方法,供HTML文檔內的ng-init指令調用。在init方法內,使用了$http服務來下載adminMenu。

    我給success方法提供了回調,當下載成功后,修改作用域的menus屬性,把從/adminMenu下載到的json數組直接賦值給menus屬性。從Node.js后端到Angular前端,json對json,無需轉換,酸爽!

    $http的get方法的參數是URI,如示例中的用法,你可以略去域名部分。你也可以使用完整的URL,比如 http://localhost :3000/adminMenu,效果是一樣一樣一樣的。

    $http服務內部使用了瀏覽器的XMLHttpRequest(XHR)對象。

    好啦,最終,你在瀏覽器內訪問“ http://localhost :3000/admin2.html”,效果可能是這樣的:

    //view-angular-admin2.png

    另一種寫法

    其實呢,這個簡單的示例,可以不用ng-init指令,這樣更簡單,admin2.html與admin.html就只有一點差異:將HTML引用的admin.js修改為admin2.js。然后呢,修改一下admin2.js,直接在控制器的構造函數內開始下載即可。新的代碼如下:

    angular.module('x-admin', []).
    controller('x-controller', ['$scope', '$http', function ($scope, $http) {
      $scope.currentUser="ZhangSan";
      $scope.content = '/welcome.html';
      $scope.menus = [];
    
      $http.get("http://localhost:3000/adminMenu")
             .success(function(data, status, headers, config){
               console.log("got menus");
               $scope.menus = data;
             })
             .error(function(data, status, headers, config){
               console.log("got menus failed. status - " + status);
             });
    
      $scope.setContent = function(action){
        console.log(action);
        $scope.content=action;
      };
    }]);

    更多的Angular服務

    Angular提供了很多內置服務,想在控制器內使用的話,在控制器構造函數的參數里直接寫上服務的名字,Angular自動會為我們完成依賴注入。

    angular.module('x-admin', []).
    controller('x-controller', ['$scope', '$http', function ($scope, $http)

    上面的代碼,x-controller的構造函數依賴scope和http,如果想使用其他的服務,比如$window,可以改成下面這樣:

    angular.module('x-admin', []).
    controller('x-controller', ['$scope', '$http', '$window', function ($scope, $http, $window)

    這種寫法太繁瑣,多輸入好些字符,我還是喜歡這樣:

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