學習 AngularJS (三) module

再看 kityminder-editor 部分代碼, 上來就是 angular module: html

angular.module('kityminderEditor', [
    'ui.bootstrap',
    'ui.codemirror',
    'ui.colorpicker'
])
       .config(...) ...

看不明白, 怎麼辦? 只能接着學習了! angularjs

查 angularjs 英文官網, 終於找到 module 的網頁了:
    https://docs.angularjs.org/guide/module bootstrap

 

因此, 什麼是一個 Module?

原文: You can think of a module as a container for the different parts of your app - controllers,
  services, filters, directives, etc. api

這樣從用途上定義了模塊(module)是一個個人應用的(雜七雜八的)各類東西的總容器.
因而, 天然而然的問題產生了, 一個 app 對應一個仍是多個 module? 一個 module 的生命週期如何? app

Why?

大部分應用有一個 main 方法來實例化對象, 並將應用的各個不一樣部分 wires(關聯起來)在一塊兒.
Angular 的應用沒有這個 main 方法. 而是用 modules 來聲明應用是如何啓動(bootstrap)的. ide

* 聲明式語法容易理解.
* 代碼打包爲可重用的 module.
* module 可按照任意順序加載, 甚至並行加載, 由於模塊延遲執行
* 單元測試只須要加載所需模塊而非全部, 從而快一些
* end-to-end 測試可以使用 module 重載配置. 函數

看一下 module 的接口, 彷佛是一組註冊/定義各類類部件的函數集合: 
   https://docs.angularjs.org/api/ng/type/angular.Module 單元測試

class angular.Module {
  provider(name, providerType) -- 註冊 provider?
  factory(name, providerFunction) -- 註冊 factory?
  service(name, ctor) -- 註冊 service
  value(name, object) -- 變量 name=object ?
  constant(name, object) -- 常量 name=object ...?
  decorator(The, This) ...修飾器 ?
  animation(name, animationFactory)
  filter(name, filterFactory) -- 註冊過濾器
  controller(name, ctor) -- 註冊控制器
  directive(name, directiveFactory) -- 應是註冊指令
  config(configFn) -- 註冊當模塊加載時執行的代碼塊, 通常對 service 配置有用.
  run(initialitionFn) -- 註冊當 injector 結束加載了全部模塊時運行的代碼塊...

  string[] requires: 依賴的其它模塊列表, injector 會加載它們在此模塊以前.
  string name -- 模塊名
}

這裏 requires[] 顯然用於解決依賴注入問題. 學習

引用這個 myApp 模塊: 如使用 <div ng-app='myApp'>. 這將啓動這個 app 使用定義的模塊. 測試

(這樣的話, 一個 app 大概就是一個 module, 估計還能夠有多個其它 module).

 

Recommended Setup

推薦將 app 分解爲多個 module, 如這樣:
* 一個 module 爲一個特性
* 一個 module 爲可重用的組件 (尤爲是 directives, filters)
* 一個應用級 (application level) module 依賴上面的 modules, 幷包含初始化代碼.

(這樣, angluar module 的概念大體 對應一個js文件, 裏面含模塊功能代碼, 及所依賴的其它模塊.
  與 NodeJS 中的使用 define(module_name, dependence, factory() {...}) 定義的模塊應是相似概念)

 

Module Loading & Dependencies

最簡單形式包含兩種可執行的代碼塊:
* 配置 -- 在 provider 註冊和配置階段執行. 此時只有 providers 和 constant 可被注入.
* 執行 -- 注入器(iinjector)建立以後執行, 用於啓動 app. 只有 instances 和 contants 可被注入.

angular.module('myModule', [])  // 聲明一個名爲 myModule 的模塊, 依賴列表爲 emtpy
  .config(function(injectables-providers) {
    // 配置塊, 能夠有任意個. 只能注入 providers (非 instances)
  })
  .run(function(injectables-instances) {
    // 運行塊, 能夠有任意個. 只能注入 instances (非 providers)
  });


(可能這裏分兩階段才能正確完成 module 的初始化, 以防止模塊相互依賴, 初始化不徹底的狀況)

 

Configuration Blocks

module.value() 方法等價於 $provide.value();
   .drective() 等價於 $compileProvider.directive() 等等.
這些在 module.config() 中以各類 $provide 方式提供.

現學現查, 從 kityminder-editor 中任意找了一個 ui/directive/arrange/arrange.directive.js:

angular.module('kityminderEditor') // 若是模塊已經存在, 估計會取出該模塊.
  .directive('arrange', [... {  // 定義指令 arrange, 依賴部分略.
    return { 此指令的實現對象 };
  }]);

再看其它 directive 形式也相似, 另再看一個 filter lang.filter.js:

angular.module('kityminderEditor')
  .filter('lang', [... function(config, lang) {
    return 工廠方法;
  }]);

估計是定義 lang 過濾器, 返回一個工廠方法, 細節先略去.

(仍是買本 angularjs 的最新技術圖書看看吧...)

 

Run Blocks

用於啓動應用, 如 angular.module('myModule').run( function () {...} );

(在 kityminder 中暫時沒找到這種塊... 只有 config 塊. 多是用 ng-app 的方式啓動應用的.)

 

Creation vs. Retrieval

(每次我瞎猜以後, 都能看到一些推翻我猜想的文檔...)

* 使用 angular.module('myModule', []) 將建立名爲 myModule 的模塊, 覆蓋原有的.
* 使用 angular.module('myModule') 獲取已存在的 module. (? 若是不存在呢)

因而下面兩個對比就終於弄明白了(其實原來也沒注意到有什麼區別...) :

// 被最早引入的 kityminder.app.js, 建立了模塊.
angular.module('kityminderEditor', [dependencies ... 略])
  .config(...);


// 後面引入的, 例如 commandBinder.service.js, 向模塊中添加 service,filter,directive 等.
angular.module('kityminderEditor')  // 注意這裏沒有 [...] 參數
  .service(...);

引入固然是用 script 標記:

<!-- 前面大量各類庫 js 引入 -->

<script src="ui/kityminder.app.js"></script>
<script src="ui/service/commandBinder.service.js"></script>
<!-- dev 模式下的 kityminder index.htm 後面還有大量的 js 引入 -->

因爲使用了這麼多 js 庫, 我都有點擔憂機器內存不夠...

相關文章
相關標籤/搜索