GUAOSHITAIDU 2016-04-25
目前没写javascript的吐槽,以后会写。
jqLite(document).ready(function() { angularInit(document, bootstrap); });上面代码在 angular.js文件最后几行,当所有的angular代码执行完毕,就执行启动。
function angularInit(element, bootstrap) { var elements = [element],//扫描到的节点,document为默认。 appElement,//第一个确认的节点,初始化只会寻找一个节点 module,//节点对应的 module名 names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],//扫描的属性名 NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/; //添加节点,看下面的forEach function append(element) { element && elements.push(element); } //寻找 names 中在dom中的节点 forEach(names, function(name) { names[name] = true; append(document.getElementById(name)); name = name.replace(':', '\\:');//这里麻烦,少见不解释。 if (element.querySelectorAll) { forEach(element.querySelectorAll('.' + name), append); forEach(element.querySelectorAll('.' + name + '\\:'), append); forEach(element.querySelectorAll('[' + name + ']'), append); } }); //寻找到第一个有效节点,查询出模块名 forEach(elements, function(element) { if (!appElement) { var className = ' ' + element.className + ' '; // 正则出 className里面的没有有模块名 var match = NG_APP_CLASS_REGEXP.exec(className); if (match) { appElement = element; module = (match[2] || '').replace(/\s+/g, ','); } else {//没有找属性 forEach(element.attributes, function(attr) { if (!appElement && names[attr.name]) { appElement = element; module = attr.value; } }); } } }); if (appElement) { bootstrap(appElement, module ? [module] : []);//得到启动节点,与模块名。就调用bootstrap方法 } }
var doBootstrap = function() { //获得节点 element = jqLite(element); //看这个节点是否已经被使用了 if (element.injector()) { var tag = (element[0] === document) ? 'document' : startingTag(element); //Encode angle brackets to prevent input from being sanitized to empty string #8683 throw ngMinErr( 'btstrpd', "App Already Bootstrapped with this Element '{0}'", tag.replace(/</, '<').replace(/>/, '>')); } //给模块绑定基础数据 modules = modules | []; modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); //初始化 注入器 var injector = createInjector(modules); //执行compile injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', '$animate', function(scope, element, compile, injector, animate) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); } ]); //返回注入器 return injector; };
//注意这个属性,识别windows的这个属性,如果不存在就立即加载, var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/; if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) { return doBootstrap(); } window.name = window.name.replace(NG_DEFER_BOOTSTRAP, ''); //在这里请注意 modules.push(module) 这里 angular.resumeBootstrap = function(extraModules) { forEach(extraModules, function(module) { modules.push(module); }); doBootstrap(); };