angular源码学习第一篇 setupModuleLoader方法


Posted in Javascript onOctober 20, 2016

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。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
sina的lightbox效果。
Jan 09 Javascript
Span元素的width属性无效果原因及解决方案
Jan 15 Javascript
JavaScript使用过程中需要注意的地方和一些基本语法
Aug 26 Javascript
一个简单的全屏图片上下打开显示网页效果示例
Jul 08 Javascript
JavaScript获取对象在页面中位置坐标的方法
Feb 03 Javascript
bootstrap laydate日期组件使用详解
Jan 04 Javascript
原生js实现淘宝购物车功能
Jun 23 Javascript
详解微信小程序开发之——wx.showToast(OBJECT)的使用
Jan 18 Javascript
js实现九宫格拼图小游戏
Feb 13 Javascript
微信小程序使用Promise简化回调
Feb 06 Javascript
iview中Select 选择器多选校验方法
Mar 15 Javascript
微信小程序实现折叠与展开文章功能
Jun 12 Javascript
jQuery动态创建元素以及追加节点的实现方法
Oct 20 #Javascript
JS中动态创建元素的三种方法总结(推荐)
Oct 20 #Javascript
yarn与npm的命令行小结
Oct 20 #Javascript
Bootstrap 网站实例之单页营销网站
Oct 20 #Javascript
Javascript的动态增加类的实现方法
Oct 20 #Javascript
关于RequireJS的简单介绍即使用方法
Oct 20 #Javascript
javascript淘宝主图放大镜功能
Oct 20 #Javascript
You might like
经典的PHPer为什么被认为是草根?
2007/04/02 PHP
在php和MySql中计算时间差的方法
2011/04/22 PHP
优化PHP代码技巧的小结
2013/06/02 PHP
通过Email发送PHP错误的方法
2015/07/20 PHP
php实现保存周期为1天的购物车类
2017/07/07 PHP
javascript 框架小结 个人工作经验
2009/06/13 Javascript
prototype 中文参数乱码解决方案
2009/11/09 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
jQuery操作Select选择的Text和Value(获取/设置/添加/删除)
2013/03/06 Javascript
JQuery对表格进行操作的常用技巧总结
2014/04/23 Javascript
原生javascript实现简单的datagrid数据表格
2015/01/02 Javascript
JavaScript返回网页中超链接数量的方法
2015/04/03 Javascript
AngularJS全局警告框实现方法示例
2017/05/18 Javascript
node 利用进程通信实现Cluster共享内存
2017/10/27 Javascript
Vue页面骨架屏注入方法
2018/05/13 Javascript
vue2实现搜索结果中的搜索关键字高亮的代码
2018/08/29 Javascript
Django+vue跨域问题解决的详细步骤
2019/01/20 Javascript
vue3 源码解读之 time slicing的使用方法
2019/10/31 Javascript
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
简单介绍Python中的readline()方法的使用
2015/05/24 Python
使用Nginx+uWsgi实现Python的Django框架站点动静分离
2016/03/21 Python
django中send_mail功能实现详解
2018/02/06 Python
对python多线程SSH登录并发脚本详解
2019/02/14 Python
django 取消csrf限制的实例
2020/03/13 Python
如何使用Pytorch搭建模型
2020/10/26 Python
Ubuntu配置Pytorch on Graph (PoG)环境过程图解
2020/11/19 Python
python urllib和urllib3知识点总结
2021/02/08 Python
Python 调用C++封装的进一步探索交流
2021/03/04 Python
任意一块网页内容实现“活”的背景(目前火狐浏览器专有)
2014/05/07 HTML / CSS
丝芙兰中国官方商城:SEPHORA中国
2018/01/10 全球购物
西班牙自行车和跑步商店:Alltricks
2018/07/07 全球购物
DC Shoes澳大利亚官方网上商店:购买DC鞋子
2019/10/25 全球购物
这段代码难道不该打印出56吗
2013/02/27 面试题
2016班级元旦联欢会开幕词
2016/03/04 职场文书
Java实现添加条码或二维码到Word文档
2022/06/01 Java/Android