# 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