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();
};