zl程序教程

您现在的位置是:首页 >  其它

当前栏目

Angularjs的IOC Inject分析

分析 angularjs IOC Inject
2023-09-14 09:00:58 时间

     在上一篇《Angularjs开发一些经验总结》中提到angular开发中的IOC inject优先,所以在这节将引用angularjs的注入代码来分析angularjs的注入方式。在《再谈angularjs DI(Dependency Injection)》中提到angularjs的注入方式分为3中方式,如果你还不清楚的请移步。

推断式注入:在angularjs中我们可以在我们需要注入的地方按照名称注入,这里要求参数名称必须和注入服务实例名称相同,一种名称约定,angularjs会提取参数名称查找相应DI实例注入; :标记注入:在angularjs中我们可以利用$inject标注DI注入,这里需要注入服务名称的顺序和构造参数名对应.这里可以解决以上约定的死板性; 内联注入:对于directives,factory,filter等特殊指令使用$inject标注注入使用不是那么友好,angularjs特别增加了内联注入。

    在这里我们先上今天的主角code:

复制代码
 1 /** 

 2 * @ngdoc overview 

 3 * @name AUTO 

 4 * @description 

 5 * 

 6 * Implicit module which gets automatically added to each {@link AUTO.$injector $injector}. 

 7 */ 

 9 var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; 

10 var FN_ARG_SPLIT = /,/; 

11 var FN_ARG = /^\s*(_?)(.+?)\1\s*$/; 

12 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; 

13 function annotate(fn) { 

14 var $inject, 

15 fnText, 

16 argDecl, 

17 last; 

19 if (typeof fn == function) { 

20 if (!($inject = fn.$inject)) { 

21 $inject = []; 

22 fnText = fn.toString().replace(STRIP_COMMENTS, ); 

23 argDecl = fnText.match(FN_ARGS); 

24 forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){ 

25 arg.replace(FN_ARG, function(all, underscore, name){ 

26 $inject.push(name); 

27 }); 

28 }); 

29 fn.$inject = $inject; 

30 } 

31 } else if (isArray(fn)) { 

32 last = fn.length - 1; 

33 assertArgFn(fn[last], fn) 

34 $inject = fn.slice(0, last); 

35 } else { 

36 assertArgFn(fn, fn, true); 

37 } 

38 return $inject; 

39 }
复制代码

 

   在上面code中我们可够很清晰的看到首先这里会判断是不是一个function,如果是的我们这会判断fn.$inject为空,不为空则返回此注入(标记注入),为空则会根据正则匹配获取参数列表,注入服务的名字按名注入;相反如果不是function而是Array的话获取前n-1的服务名称注入,这是内联注入。

 

  关于angularjs注入就到这里,在最后想说下说这代码中我们能获取的两个javascript技巧:

对于javascript是运行时解释的弱类型语言,我们无法利用c#,java类似的反射机制去获取参数信息,我们只能靠正则从javascript代码中匹配(从function.toString()). 正则的强大之处,在javascript中replace函数的强大应用:
arg.replace(FN_ARG, function(all, underscore, name){ 

$inject.push(name); 

});