Angular.js

辅助函数

  • lowercase
  • hasOwnProperty
  • uppercase
  • mannualLowercase
  • mannualUppercase
  • isArrayLike
  • forEach
  • reverseParams

核心功能

  • angularInit(element, bootstrap)

    找到带有ng-app的节点,读取module,在该节点上启动bootstrap。

  • bootstrap(element, modules, config)

    先往modules中加入“provide”, “ng”两个module,然后调用createInjector(modules, config.strictDi)创建一个injector,再之后如下:

injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
function bootstrapApply(scope, element, compile, injector) {
scope.$apply(function() {
element.data('$injector', injector);
compile(element)(scope);
});
}]
);

其实也就是手动调用了一个$scope的更新过程,所以重点在于createInjector和compile两个函数了。

auto/injector.js

辅助函数

  • extractArgs(fn)

    从javascript函数对象中把参数读出来,这个利用了javascript函数的toString()的方法会返回函数的定义的特点。
  • anonFn(fn)

    为一个函数取一个名字
  • annotate(fn, strictDi, name)

    为一个函数添加一个$inject对象,里面存入函数参数列表(?这个还不太确定)

核心函数

injector的主入口是createInjector(modulesToLoad, strictDi),解析这个函数需要一步一步的来:

首先我们必须对Injector的结构有一个透彻了解,参见函数createInternalInjector(cache, factory)。

  • createInternalInjector(cache, factory)

    返回一个injector对象,其中各个属性如下:

    * get(serviceName, caller)

    试图从cache中取出service对象,否则则调用factory(serviceName, caller)并将结果存入cache.

    * injectionArgs(fn, locals, serviceName)

    fn获取其参数列表,然后按照locals[key], getService(key, serviceName)的优先级获取fn的参数返回。

    * invoke(fn, self, locals, serviceName)

    调用injectionArgs(fn, locals, serviceName)实例化arguments, 然后调用fn函数。

    * instantiate(Type, locals, serviceName)

    第一个Type是构造函数,同样调用injectionArgs(Type, locals, serviceName)实例化arguments,然后调用构造函数获取实例并且返回。

    injector的get方法会总是试图从cache中取出实例,当实例不存在时,调用factory方法处理。invoke和instantiate都是先从函数中获取参数列表,然后用locals和cache来实例化参数,然后调用函数获取结果。

  1. 新建了一个变量providerCache,作为所有provider的cache,同时该cache中预存了$provide对象,里面提供了以下方法:

    • provider(name, provider_)
    • factory(name, factoryFn, enforce)
    • service(name, constructor)
    • value(name, value)
    • decorator(serviceName, decorFn)

    除了最后的decorator,这一系列方法都是在providerCache中存入一个包含$get方法的provider。该方法会在各个模块的configProvider中使用,将provider存在providerCache中去。

  2. 利用刚刚的providerCache建立第一个injector: providerInjector, 其factory方法会报错提示provider不存在。

  3. 用一个空对象建立第二个injector: instanceInjector,不同的是它的factory方法,该方法总是先试图用providerInjector获取其provider,然后调用instanceInjector.invoke(provider.$get, provider, undefined, serviceName)。

  4. 在providerCache中加入$injector的provider,因此可以通过injector获取injector自身。

    总结一下,injector基于某一个cache来进行实例的存取和函数参数的实例化,对于不存在的实例,各个injector处理方法不一样,providerInjector是会报错的,而intanceInjector会调用providerInjector首先获取provider,然后实例化instance,最后存入instanceCache中。

  5. 调用loadModules(modulesToLoad),最后使用instanceInjector来invoke返回的runBlocks。

loadModules的内容相对比较直接,阅读其源代码可知道主要做了以下三件事:

1. 加载该module require的modules

2. runInvokeQueue(module._invokeQueue)

2. runInvokeQueue(module._configBlocks)

3. 返回modules的_runBlocks

	runInvokeQueue方法的代码如下:
function runInvokeQueue(queue) {
var i, ii;
for (i = 0, ii = queue.length; i < ii; i++) {
var invokeArgs = queue[i],
provider = providerInjector.get(invokeArgs[0]); provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
}
}
```

loader.js

可以通过阅读下setupModuleLoader的代码来了解angular的module机制。

首先需要了解函数invokeLater(provider, method, insertMethod, queue)和invokeLaterAndSetModuleName(provider, method),当insertMethod, queue都没有提供的时候,它返回匿名函数,该函数调用时将会在queue中inserMethod进[provider, method, arguments]的一个数组。该数组将会被injector调用。如上一章的code所示,它将会先取出provider,然后调用其method(arguments)。

这里我们看到module.provider的定义是invokeLaterAndSetModuleName('$provide', 'provider')

因此当我们调用angular.module(test).provider()时,它将会在该module的queue里存入相应的数据,之后在angular初始化时,它将会用providerInjector取出$provide服务,然后我们可以调用它里面的各种预存方法,从而将provider预存进providerCache。

AngularJS Source code的更多相关文章

  1. Tips for newbie to read source code

    This post is first posted on my WeChat public account: GeekArtT Reading source code is always one bi ...

  2. 编程等宽字体Source Code Pro(转)

    Source Code Pro - 最佳的免费编程字体之一!来自 Adobe 公司的开源等宽字体下载     每一位程序员都有一套自己喜爱的代码编辑器与编程字体,譬如我们之前就推荐过一款"神 ...

  3. How to build the Robotics Library from source code on Windows

    The Robotics Library is an open source C++ library for robot kinematics, motion planning and control ...

  4. How to build windows azure PowerShell Source Code

    Download any version source code of Windows Azure Powershell from https://github.com/Azure/azure-sdk ...

  5. akka cluster sharding source code 学习 (1/5) 替身模式

    为了使一个项目支持集群,自己学习使用了 akka cluster 并在项目中实施了,从此,生活就变得有些痛苦.再配上 apache 做反向代理和负载均衡,debug 起来不要太酸爽.直到现在,我还对 ...

  6. view class source code with JAD plugin in Eclipse

    The default class viewer doesn't decompile the class file so you cannot open and check the source co ...

  7. Classic Source Code Collected

    收藏一些经典的源码,持续更新!!! 1.深度学习框架(Deep Learning Framework). A:Caffe (Convolutional Architecture for Fast Fe ...

  8. Attach source code to a Netbeans Library Wrapper Module

    http://rubenlaguna.com/wp/2008/02/22/attach-source-code-to-a-netbeans-library-wrapper-module/ Attach ...

  9. convert source code files to pdf format in python

    import os import sys def find_file(root_dir, type): dirs_pool = [root_dir] dest_pool = [] def scan_d ...

随机推荐

  1. servlet ; basepath ; sendredirected ;

    Eclipse 新建 jsp页面里自动生成以下代码: <%String path = request.getContextPath();String basePath = request.get ...

  2. 【BZOJ2653】middle 二分+可持久化线段树

    [BZOJ2653]middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个 ...

  3. angularjs中的$destroy和$timeout

    module.controller("TestController", function($scope, $timeout) { var onTimeout = function( ...

  4. css 特殊处理样式记录

    1.解决任何盒子的垂直横向 居中显示 display: -webkit-box; -webkit-flex: 1; -webkit-box-orient: vertical; -webkit-box- ...

  5. IO流入门-概述

    纲要 Java流概述 文件流 缓冲流 转换流 打印流 对象流 File类 流的概念 按方向划分:输入流和输出流,是相对内存而言的.从内存出来是输出,到内存中就是输入.输入流又叫做InputStream ...

  6. Restful风格到底是什么?怎么应用到我们的项目中?

    rest越来越流行,感觉挺高大尚的.网上看了很多网友的说法,各有各的看法,我觉得很多说得很有道理. 说法一 restful风格,就是一种面向资源服务的API设计方式,它不是规范,不是标准,它一种设计模 ...

  7. lombok插件使用

    1.1 lombok介绍 lombok 是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写,可以通过采用注解的方式,消除代码中的构造方法,getter/setter等代码 ...

  8. Codeforce 475 C. Kamal-ol-molk&#39;s Painting

    从最左上的点開始枚举长宽.... C. Kamal-ol-molk's Painting time limit per test 2 seconds memory limit per test 256 ...

  9. vuejs项目打包成APP后,首页不显示

  10. 用仿ActionScript的语法来编写html5——第四篇,继承与简单的rpg

    第四篇,继承与简单的rpg 这次用继承自LSprite的类来实现简单的rpg的demo先看一下最后的代码与as的相似度 var backLayer; //地图 var mapimg; //人物 var ...