zoukankan      html  css  js  c++  java
  • AngularJS Source code

    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。

  • 相关阅读:
    Interesting Finds: 2009 01.15 ~ 01.17
    Interesting Finds: 2008.12.07
    Interesting Finds: 2008.12.31
    10月16号
    10月14号
    10月15号
    10月13号
    10月20号
    10月19号
    10月12号
  • 原文地址:https://www.cnblogs.com/lkiversonlk/p/5121302.html
Copyright © 2011-2022 走看看