angular 源码分析 1 - angularInit()
angularjs 是个神奇的框架,由于我的好奇,想了解她的内部工作原理,只能一步一步的走进她,靠近她,和她深入的交流。
angularjs 的入口是什么样子的呢?一起掀起她的盖头吧。
在这里我只讲方法,具体的行号不做记录,自己找吧(Ctrl+F);
入口是这样的:
jqLite(document).ready(function() { angularInit(document, bootstrap); });
原理简单,就是获取document ready 结束时,调用angularInit(document, bootstrap); 我们今天的重头戏是angularInit()方法, 暂时不讲bootstrap。
1 var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-']; 2 function angularInit(element, bootstrap) { 3 var appElement, 4 module, 5 config = {}; 6 7 // The element `element` has priority over any other element 8 forEach(ngAttrPrefixes, function(prefix) { 9 var name = prefix + 'app'; 10 11 if (!appElement && element.hasAttribute && element.hasAttribute(name)) { 12 appElement = element; 13 module = element.getAttribute(name); 14 } 15 }); 16 forEach(ngAttrPrefixes, function(prefix) { 17 var name = prefix + 'app'; 18 var candidate; 19 20 if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) { 21 appElement = candidate; 22 module = candidate.getAttribute(name); 23 } 24 }); 25 if (appElement) { 26 config.strictDi = getNgAttribute(appElement, "strict-di") !== null; 27 bootstrap(appElement, module ? [module] : [], config); 28 } 29 }
这个方法就是angularjs 获取ng-app (['ng-', 'data-ng-', 'ng:', 'x-ng-'] app有这几种写法)的方法, 8~24行都是为了寻找整个页面中的app属性,此时只会获取第一个带有app的属性元素,这也是为什么一个程序中只能有一个app的原因,如果找到了带有app的属性,就执行26~27行代码,如果没有找到,对不起,angularjs 没有了卵用,这就为什么必须刚开始写ng-app="XXXX"。
那么26行是什么意思呢?
1 function getNgAttribute(element, ngAttr) { 2 var attr, i, ii = ngAttrPrefixes.length; 3 for (i = 0; i < ii; ++i) { 4 attr = ngAttrPrefixes[i] + ngAttr; 5 if (isString(attr = element.getAttribute(attr))) { 6 return attr; 7 } 8 } 9 return null; 10 }
就是判断 是严格模式吗,即在app的元素上 写ng-strict-di属性了吗,当找到了就返回获取的属性值,没有找到就返回null;
你可能有疑惑什么是严格模式,自己看看吧,https://docs.angularjs.org/api/ng/directive/ngApp 搜搜“ ngStrictDi ”,自己可以试试。
执行完getNgAttribute() 返回的值进行判断后 赋给了config.strictDi(true/false)。
好了,先讲这些吧,下次讲讲bootstrap()方法