# 4. 依賴注入
**injector** , 我從 ng 的文檔中得知這個概念,之后去翻看源碼時了解了一下這個機制的工作原理。感覺就是雖然與自己的所想僅差那么一點點,但就是這么一點點,讓我感慨想象力之神奇。
先看我們之前代碼中的一處函數定義:
var BoxCtrl = function($scope, $element){}
在這個函數定義中,注意那兩個參數: _$scope_ , _$element_ ,這是兩個很有意思的東西。總的來說,它們是參數,這沒什么可說的。但又不僅僅是參數——你換個名字代碼就不能正常運行了。
事實上,這兩個參數,除了完成“參數”的本身任務之外,還作為一種語法糖完成了“依賴聲明”的任務。本來這個函數定義,完整的寫法應該像 AMD 聲明一樣,寫成:
var BoxCtrl = ['$scope', '$element', function(s, e){}];
這樣就很明顯,表示有一個函數,它依賴于兩個東西,然后這兩個東西會依次作為參數傳入。
簡單起見,就寫成了一個函數定義原本的樣子,然后在定義參數的名字上作文章,來起到依賴聲明的作用。
在處理時,通過函數對象的 _toString()_ 方法可以知道這個函數定義代碼的字符串表現形式,然后就知道它的參數是 _$scope_ 和 _$element_ 。通過名字判斷出這是兩個外部依賴,然后就去獲取資源,最后把資源作為參數,調用定義的函數。
所以,參數的名字是不能隨便寫的,這里也充分利用了 js 的特點來盡量做到“反省”了。
在 Python 中受限于函數名的命名規則,寫出來不太好看。不過也得利于反省機制,做到這點也很容易:
# -- coding: utf-8 --
def f(Ia, Ib):
print Ia, Ib
args = f.func_code.co_varnames
SRV_MAP = {
'Ia': '123',
'Ib': '456',
}
srv = {}
for a in args:
if a in SRV_MAP:
srv[a] = SRV_MAP[a]
f(**srv)
- Introduction
- 關于AngularJS
- 關于本文檔
- 開始的例子
- 依賴注入
- 作用域
- 數據綁定與模板
- 數據->模板
- 模板->數據
- 數據->模板->數據->模板
- 模板
- 定義模板內容
- 內容渲染控制
- 節點控制
- 事件綁定
- 表單控件
- 模板中的過濾器
- 排序 orderBy
- 過濾列表 filter
- 其它
- 例子:表頭排序
- 例子:搜索
- 錨點路由
- 路由定義
- 參數定義
- 業務處理
- 定義模板變量標識標簽
- AJAX
- HTTP請求
- 廣義回調管理
- 工具函數
- 上下文綁定
- 對象處理
- 類型判定
- 其它服務
- 日志
- 緩存
- 計時器
- 表達式函數化
- 模板單獨使用
- 自定義模塊和服務
- 模塊和服務的概念與關系
- 定義模塊
- 定義服務
- 引入模塊并使用服務
- 附加模塊 ngResource
- 使用引入與整體概念
- 基本定義
- 基本使用
- 定義和使用時的占位量
- 實例
- AngularJS與其它框架的混用(jQuery, Dojo)
- 自定義過濾器
- 自定義指令directive
- 指令的使用
- 指令的執行過程
- 基本的自定義方法
- 屬性值類型的自定義
- Compile的細節
- transclude的細節
- 把節點內容作為變量處理的類型
- 指令定義時的參數
- Attributes的細節
- 預定義的 NgModelController
- 預定義的 FormController
- 示例:文本框
- 示例:模板控制語句 for
- 示例:模板控制語句 if/else