angular源码阅读的起点,setupModuleLoader方法

angular源码其实结构非常清晰,划分的有条有理的,大概就是这样子:

(function(window,document,jquery,undefined){
  //一些工具函数
  //EXPR 编译器 自执行
  //setupModuleLoader方法,公司内部的框架是vxsetup方法,(只是定义,没有调用)
  //moduler方法()
  //angular初始化方法,公司内部的框架是vxinit方法
  //bootstrap
  //createInjector
  //一系列指令,服务,过滤器等指令
})(window,document,window.$)

其实阅读angular源码重要的是angular的整个架构思路,至于服务过滤器和指令可以先抛开。

setupModuleLoader方法写的有点复杂,尤其是直接三层闭包,如果逆着看,容易糊涂,还是顺着思路走比较容易。

首先是,我希望当我运行angualr的时候,可以在window下面创建一个angular属性。这个angualr是一个对象,可以用来创建一个module。于是产生了下面的代码:

function setupModuleLoader(window){

        //ensure方法比较通俗易懂,网上也很多解释。由此看来,window.angular这个对象是个单例的。

	var ensure=function(obj,name,factory){
		return obj[name]||(obj[name]=factory())
	}

	var angular = ensure(window,‘angular‘,Object);

        //createModule方法是用来创建一个module实例的。
	var createModule = function(name,requires){
		var moduleInstance = {
			name:name,
                        requires:requires
		};
		return moduleInstance;
	}
        //window.angular.module方法实际运行的是createModule方法,这个闭包只是为了保护一下变量(现在是简化版,变量还没有加)。
        //其实要给一个对象增加一个方法,在angular中经常使用ensure函数,传一个工厂函数,这样的好处是整齐并且保护作用域。
	ensure(angular,‘module‘,function(){
		return function(name,requires){
			return createModule(name,requires)
		}
	})

}

  

现在看起来这个angular.module方法就是这样了。这是注册的方法。

众所周知的是,angular.module(‘myapp‘,[])这段代码是注册一个module,如果不传后面的第二个参数,就是取回一个app。

然而目前上面写的代码并没有取回一个module的功能。所以需要完善一下:

function setupModuleLoader(window){
	var ensure=function(obj,name,factory){
		return obj[name]||(obj[name]=factory())
	}
        //增加一个对象,用于存放每一个注册过的module,其实在angular里面,这个对象也是存在的
        //当然,这个modules对象的位置是在下面ensure(angular,‘module‘,fn)的fn工厂函数里,这样放在闭包里就可以杜绝外界访问
        //如果你改一下angular的源码,把这个对象强行获取到,比如设置window.modulebox = modules;然后再去打印这个modulebox来看,你会发现所有注册的modules都能看到。
        //我放到这里是因为以后方便调试。我可以随时看到modules里面都有什么东西。但是其实不影响的。
        var modules={}

	var angular = ensure(window,‘angular‘,Object);

	var createModule = function(name,requires,modules){
		var moduleInstance = {
			name:name
		};
                modules[name]=moduleInstance;//每注册一个module的时候都把这个module按照相应名称存入modules对象。
		return moduleInstance;
	}

	ensure(angular,‘module‘,function(){
		return function(name,requires){
			if(requires){
				return createModule(name,requires,modules)//增加了一个参数,就是modules这个对象。
			}else{
				return getModule(name,modules);//这个getModule方法虽然还没定义,但是这一段代码看起来确实很明白了。g
			}
		}
	})
}

  

现在OK了,可以注册一个module也可以获取一个module了。至于getModules就是根据名称从modules对象中取出一个module,就不写了。

其实简化下来的setupModuleLoader就是这样,挺清晰的。

setupModuleLoader方法真正开始变的复杂是从它与injector的配合开始。

setupModuleLoader方法先放到这儿,下一篇分析一下injector方法。然后回过头来在搞setupModuleLoader。

看看他们是怎么配合的。

重要的是,injector这个东西一定要先理解透彻,同时$provider我希望看到这篇博客的你(当然也包括我)能够理解透彻。

这样的话会很容易搞懂angularJs。

晚安!

  

时间: 2024-10-15 23:22:20

angular源码阅读的起点,setupModuleLoader方法的相关文章

ubuntu下linux内核源码阅读工具和调试方法总结

http://blog.chinaunix.net/uid-20940095-id-66148.html 一 linux内核源码阅读工具 windows下当然首选source insight, 但是linux下就没有source insight这么优秀的工具了,但是也有不少的替代品,但觉绝对部分人会选择vim+ctags+cscope的组合,还有部分人或选择wine中的source insight或选择navigatror,当然对于代码阅读来说vim+ctags+cscope的组合还是比较好的一

angular源码阅读3:真的,依赖注入的原理

前面已经提到了: 如何注册一个module. 如何获取一个module. injector与module以及provider的关系. 那么已经剩下最后一部分了,就是关于依赖是如何被注入的. 且看下面这段代码. //如你所见,注册了一个moduleA //又如你所见,给moduleA上面注册了两个全局变量,a和b angular.module('moduleA',[]); angular.module('moduleA').constant('a',1); angular.module('modu

源码阅读的方法

小弟我入行不久,实打实的菜鸟,最近由于个人兴趣和工作需要,读了一些源码,感觉还不错,谨以此文做个小小的总结以达到抛砖引玉之效,如有错误和不足的地方希望各位补充. 感谢开源,让我这种并没有受过系统的软件开发训练的工程师也能学习到业界一流的代码,并通过源代码和一些顶尖的程序员零距离的对话.源码对于我这种经验算不上丰富的小白来说是恐怖的,但真正开始的时候却也是魅力无限的,当全身心地沉浸在代码中时,专注和兴奋度远大于听一次讲座或者看一本书,但如果方法不对则很有可能刚刚形成的勇气和兴趣会被无情地摧毁. 我

源码阅读系列:源码阅读方法

一.前提条件 1.纯熟扎实的语言基础 ??如果你学java,却对反射.泛型.注解一直半解,还是不要去读什么框架了,回去把java基础打扎实反而对你自身更有益. 2.UML能力 ??在软件工程中,UML在软件的不同生命周期阶段扮演着非常重要的角色,没有好的UML水平,面对大型的项目源码会束手无策. 3.对业务的理解 ??如果你要阅读的项目业务性比较强,事先对业务有一定的了解是必须的. 4.设计模式.重构的掌握 ??编程语言什么的没什么好说.着重提一个:设计模式由于Android源代码用到各种各样的

【转】Java开源项目源码阅读方法及二次开发方法

一直以来,都想要阅读某些Java开源项目的源代码,甚至想要修改某些代码,实现对开源项目进行二次开发的目的.但总是不知从何入手,直接将开源项目的源代码导入Eclipse,总是会报很多错误,而无法编译.可以直接通过Eclipse打开开源项目的源代码,至少能够达到可视化源码阅读.源码导航的目的,还是能在一定程度上解决源码阅读不爽的问题,因为直接打开并没有改变源文件项目的目录结果,对于修改过后的代码,可以通过命令行找到源文件项目目录,并使用mvn或者ant对项目进行编译,再查看修改后的项目是否正确. 由

javascript源码阅读推荐

学习任何程序设计语言,看书都只是开始的一小步而已,多看别人写的代码,自己动手多写代码才能让自己更上一层楼.Javascript的语言使用更是如此,由于javascript运行环境是浏览器,长久以来JavaScript兼容性一直是web开发者的一个主要问题.在正式规范.事实标准以及各种实现之间的存在的差异让许多开发者日夜煎熬.其结果就是很多网页不能在各种浏览器上都有一样的表现,甚至根本不能跨浏览器.但基本上都遵循ECMA-262.努力并坚持一定会提高的.来自http://furzoom.com/j

【 js 基础 】【 源码学习 】backbone 源码阅读(二)

最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-study)进行参考交流,有详细的源码注释,以及知识总结,同时 google 一下 backbone 源码,也有很多优秀的文章可以用来学习. 我这里主要记录一些偏设计方向的知识点.这篇文章主要讲 控制反转. 一.控制反转 上篇文章有说到控制反转,但只是简略的举了个例子,在这里我们详细说一下这个知识点,它其实

CI框架源码阅读笔记3 全局函数Common.php

从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap引导文件都会最先引入全局函数,以便于之后的处理工作). 打开Common.php中,第一行代码就非常诡异: if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 上一篇(CI框架源码阅读笔记2 一切的入口 index

淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划

body, td { font-family: tahoma; font-size: 10pt; } 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划 SQL编译解析三部曲分为:构建语法树,生成逻辑计划,指定物理执行计划.第一步骤,在我的上一篇博客淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树里做了介绍,这篇博客主要研究第二步,生成逻辑计划. 一. 什么是逻辑计划?我们已经知道,语法树就是一个树状的结构组织,每个节点代表一种类型的语法含义.如