2014年7月13日 星期日

AngularJS 教學 - Module

這篇我介紹一下 Module 在 AngularJS 中扮演的角色,在正式介紹之前

其實在任何一個 AngularJS 的應用程式你都已經有使用到了

沒錯,就是 ng-app 這個 AngularJS 的 Directive,可以看 AngularJS 教學 - 第一個AngularJS App

所以這邊就不再多加解釋 ng-app 了

那我們就來詳細說一下 AngularJS 的 Module:

  • 什麼是 Module
          Module 就是模組的意思,它能夠幫助我們組織整個應用程式的元件(Controller、Model、Filters...)
          因此除了幫助我們更好理解整體架構外,也可以讓整個應用程式的各種元件可以分散在
          正確的 JS 檔案內,並透過 script 標籤載入這些元件,畢竟真實世界中的大型專案,並非
          像我們之前的範例這樣,將所有的 JS 程式寫在 HTML 內。

  • Module 的使用時機
          建議再做任何 AngularJS 的專案時,最好多多利用 Module 的概念去組織你的程式
          除了有上述的優點之外,也可以再多個 AngularJS 的應用中重覆使用(reuse)你的 Module

接下來就來介紹一下,該怎樣運用 Module 來組織你的 AngularJS 應用程式,

我以下面這個範例來做解釋

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="demoApp">
     <head>
         <title>Examples</title>
         <script type="text/javascript" src="js/angular.min.js"></script>
         <script>
              var demoApp = angular.module("demoApp", []);
              demoApp.controller("demoCtrl1", function($scope){
                  //....
             });
             demoApp.controller("demoCtrl2", function($scope){
                  //....
             });
             demoApp.factory("todoService", function(){
                  //....
             });
             demoApp.directive("specSelect", function(){
                  return function(scope, element, attrs){
                       //...
                  };
              })
         </script>
     </head>
     <body>
         <div ng-controller="demoCtrl1">
              ......
         </div>
         <div ng-controller="demoCtrl2">
             ......
         </div>
     </body>
</html>

可以看到這樣一個應用程式有兩個 Controller,一個 Service,一個Directive,全部程式

都塞在 HTML 理面,除了沒有組織性外,當專案越來越大時會更難以維護及理解

所以通常我們模組化第一部就是先將 Javascript 程式從 HTML 中抽離

1. 分離 Javascript 程式
    建立 app.js
    將原本的 javascript 程式搬到 app.js

     var demoApp = angular.module("demoApp", []);
         demoApp.controller("demoCtrl1", function($scope){
              //....
   });
   demoApp.controller("demoCtrl2", function($scope){
              //....
   });
   demoApp.factory("todoService", function(){
              //....
   });
   demoApp.directive("specSelect", function(){
       return function(scope, element, attrs){
                  //...
       };
   });
     修改 index.html
     取代了原本的 script,這邊就是需要用 script 標籤載入 app.js

     <!DOCTYPE html>
   <html xmlns="http://www.w3.org/1999/xhtml" ng-app="demoApp">
     <head>
         <title>Examples</title>
         <script type="text/javascript" src="js/angular.min.js"></script>
         <script type="text/javascript" src="js/app.js"></script>
     </head>
     <body>
         <div ng-controller="demoCtrl1">
              ......
         </div>
         <div ng-controller="demoCtrl2">
             ......
         </div>
     </body>
    </html>     

2. 分離各種元件 (我以 Controller 為例)
    建立 controller.js
    我將所有 Controller 的定義都抽離到一支單獨的 JS 檔案中,並將這些 Controller 
    都支配到 demoApp.controllers 這個子模組底下 

    angular.module('demoApp.controllers', [])
      .controller("demoCtrl1", function($scope){
              //....
      }).controller("demoCtrl2", function($scope){
              //....
      });
     
    在 app.js 中加入依賴關係
    這邊就是重點了,除了建立一個 demoApp 模組之外,我也指明了這個 demoApp 模組
    需要依賴 demoApp.controllers 這個模組,沒錯 angular.module 函式的第二個參數是一個陣列型態
    陣列內的值就是這個模組所需要依賴的模組

    var demoApp = angular.module("demoApp", [
     "demoApp.controllers"
  ]);
   
    在 index.html 中載入 controller.js
    因為我額外獨立了 controller.js 這個檔案,因此要在 index.html 載入該 JS 檔

    <script type="text/javascript" src="js/controller.js"></script>


最後執行完之後你的 app.js 應該就只剩下單純的定義 demoApp 模組,並且他可能會依賴很多其他的模組,這也達到了 reuse 的目的,將各種功能性類似的程式規劃成一套模組就可以讓其他模組重覆使用該模組。

包括 Controller、Model、Service、Directive......等等的

最後我放上最終的範例

index.html 
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="demoApp">
     <head>
         <title>Examples</title>
         <script type="text/javascript" src="js/angular.min.js"></script>
         <script type="text/javascript" src="js/app.js"></script>
         <script type="text/javascript" src="js/controller.js"></script>
      <script type="text/javascript" src="js/service.js"></script>
      <script type="text/javascript" src="js/directive.js"></script>
     </head>
     <body>
         <div ng-controller="demoCtrl1">
              ......
         </div>
         <div ng-controller="demoCtrl2">
             ......
         </div>
     </body>
</html>

app.js
var demoApp = angular.module("demoApp", [
          "demoApp.controllers",
       "demoApp.services",
       "demoApp.directives",
]);

controller.js
angular.module('demoApp.controllers', [])
  .controller("demoCtrl1", function($scope){
      //....
}).controller("demoCtrl2", function($scope){
      //....
});

service.js
angular.module('demoApp.services', [])
     .factory("todoService", function(){
     //....
});
directive.js
angular.module('demoApp.directives', [])
     .directive("specSelect", function(){
          return function(scope, element, attrs){
              //...
          };
});

沒有留言:

張貼留言