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 相关文章推荐
基于jQuery的ajax功能实现web service的json转化
Aug 29 Javascript
JS实现网页右侧带动画效果的伸缩窗口代码
Oct 29 Javascript
实例讲解jquery中mouseleave和mouseout的区别
Feb 17 Javascript
全面了解addEventListener和on的区别
Jul 14 Javascript
AngularJS包括详解及示例代码
Aug 17 Javascript
javascript 中的console.log和弹出窗口alert
Aug 30 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
Feb 08 Javascript
解决vue-cli创建项目的loader问题
Mar 13 Javascript
Bootstrap Table 双击、单击行获取该行及全表内容
Aug 31 Javascript
基于JavaScript获取base64图片大小
Oct 18 Javascript
浅谈vue中$bus的使用和涉及到的问题
Jul 28 Javascript
详解vue3.0 的 Composition API 的一种使用方法
Oct 26 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
两级联动select刷新后其值保持不变的实现方法
2014/01/27 PHP
php生成xml时添加CDATA标签的方法
2014/10/17 PHP
ThinkPHP在新浪SAE平台的部署实例
2014/10/31 PHP
19个Android常用工具类汇总
2014/12/30 PHP
php查询whois信息的方法
2015/06/08 PHP
Apache+PHP+MySQL搭建PHP开发环境图文教程
2020/08/06 PHP
jQuery function的正确书写方法
2013/08/02 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
2016/01/05 Javascript
js和jquery实现监听键盘事件示例代码
2020/06/24 Javascript
用JS写的一个Ajax库(实例代码)
2016/08/06 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】
2017/06/26 jQuery
Vue 组件封装 并使用 NPM 发布的教程
2018/09/30 Javascript
微信小程序之事件交互操作实例分析
2018/12/03 Javascript
微信小程序实现的一键拨号功能示例
2019/04/24 Javascript
json数据格式常见操作示例
2019/06/13 Javascript
Python格式化压缩后的JS文件的方法
2015/03/05 Python
Python发送email的3种方法
2015/04/28 Python
利用ctypes提高Python的执行速度
2016/09/09 Python
使用Python将数组的元素导出到变量中(unpacking)
2016/10/27 Python
Python+Wordpress制作小说站
2017/04/14 Python
Python获取本机所有网卡ip,掩码和广播地址实例代码
2018/01/22 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
Python 控制终端输出文字的实例
2019/07/12 Python
python实现的分析并统计nginx日志数据功能示例
2019/12/21 Python
世界上最大的各式箱包网络零售店:eBag
2016/07/21 全球购物
澳大利亚首屈一指的在线购物目的地:Kogan.com
2017/02/02 全球购物
捐款倡议书
2014/04/14 职场文书
2014年入党积极分子党校培训心得体会
2014/07/08 职场文书
防灾减灾宣传标语
2014/10/07 职场文书
大学生见习报告范文
2014/11/03 职场文书
普通员工辞职信范文
2015/05/12 职场文书
严以律己专题学习研讨会发言材料
2015/11/09 职场文书
Javascript webpack动态import
2022/04/19 Javascript
hive数据仓库新增字段方法
2022/06/25 数据库
postgresql如何找到表中重复数据的行并删除
2023/05/08 MySQL