angular源码学习
angular.bootstrap
参数:element,modules,config
执行步骤:
- 1、修正参数config,如果config不是object,则将config设置为一个空object;
- 2、config继承自默认配置,并覆盖默认配置中的同名参数;
- 3、如果存在window对象,并且window.name含有NG_ENABLE_DEBUG_INFO标记,则将config.debugInfoEnabled设置为true,同时修正window.name,去掉debug标记;
- 4、如果window.name没有延迟引导的标记(NG_DEFER_BOOTSTRAP),则开始引导,进入第5步,否则,进入第14步;
- 5、将element包装为jqLite对象;
- 6、检测element上是否已经存在injector,如果存在,则说明已经引导过了,抛出异常,否则,继续下一步;
- 7、修正modules参数;
- 8、设置$rootElement;
- 9、如果config.debugInfoEnabled为true,则强制覆盖其他modules中的debugInfoEnabled参数;
- 10、添加ng模块;
- 11、创建injector;
- 12、编译、连接element及其children;
- 13、返回injector,引导结束;
- 14、清除window.name中的延迟标记;
- 15、在全局angular上添加resumeBootstrap方法,可以传入另外的modules参数,等待外部调用,外部调用时,就进入了第5步;
compile编译步骤
compile声明:function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) { … }
执行步骤:
- 1、如果$compileNodes不是jqLite对象,则转换成jqLite对象;
- 2、将文本节点用span标签包裹起来;
- 3、使用compileNodes函数编译节点,并生成连接函数compositeLinkFn(运用函数compositeLinkFn);
- 4、给当前编译中的节点添加class标记;
- 5、返回给外部连接函数。
compileNodes函数执行步骤:
- 1、遍历nodeList,针对每个node,执行如下2-6的步骤;
- 2、搜集node中的指令(运用函数collectDirectives);
- 3、如果该节点中存在指令,则为该节点生成连接函数nodeLinkFn(运用函数applyDirectivesToNode),否则nodeLinkFn为null;
- 4、TODO: if (nodeLinkFn && nodeLinkFn.scope) …;
- 5、TODO: childLinkFn = …;
- 6、如果nodeLinkFn或者childLinkFn存在,则将其暂存在linkFns数组;
- 7、如果linkFns不为空数组,则返回compositeLinkFn函数作为连接函数;
link连接步骤
link函数样子:function publicLinkFn(scope, cloneConnectFn, options) { … }
- 1、检测scope参数是否存在,如果不存在,抛出异常;
- 2、TODO: if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) { … };
- 3、TODO: if (!namespace) { …;
- …
digest过程
- 1、执行$digest函数的时候是同步的,也就是说在执行$digest的过程中,非$digest的代码是得不到执行的机会的;
- 2、在asyncQueue队列里面存放了一系列asyncTask,每一个asyncTask的结构大致如下:{scope: this, expression: expr}。在digest过程之外可能会存放一些asyncTask到asyncQueue中,这些asyncTask中的expression在执行的时候就处在了digest过程中,所以如果在这些asyncTask中执行$digest方法就会抛出digest in progress的异常。那么哪些expression会处在digest过程中呢?目前知道的:controller中的工厂方法。
angular中的知识点