为加深我们对angular的进一步理解,给大家准备了一些骨头,希望各位分头去啃,然后与大家分享。
服务具有唯一的名字,所以无论这个服务被注入到任何地方,对象始终只有一个实例。(银角大王举起葫芦说:我叫你一声,你敢答应吗)啥意思?
你不必关心怎么创建一个实例,只需要声明自己需要哪个服务,就会自动送到你碗里来。(咦,这不是哆啦A梦的百宝袋么?)啥意思?
按照每个程序猿的编程习惯,你可以选择方式的菜谱来自定义服务。(Angular给你准备的5道菜:Value, Factory, Service, Provider and Constant)啥意思?



function $AnchorScrollProvider() {
var autoScrollingEnabled = true;
this.disableAutoScrolling = function() {
autoScrollingEnabled = false;
};
this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
var document = $window.document;
function getFirstAnchor(list) {
var result = null;
Array.prototype.some.call(list, function(element) {
if (nodeName_(element) === 'a') {
result = element;
return true;
}
});
return result;
}
function getYOffset() {
var offset = scroll.yOffset;
if (isFunction(offset)) {
offset = offset();
} else if (isElement(offset)) {
var elem = offset[0];
var style = $window.getComputedStyle(elem);
if (style.position !== 'fixed') {
offset = 0;
} else {
offset = elem.getBoundingClientRect().bottom;
}
} else if (!isNumber(offset)) {
offset = 0;
}
return offset;
}
function scrollTo(elem) {
if (elem) {
elem.scrollIntoView();
var offset = getYOffset();
if (offset) {
var elemTop = elem.getBoundingClientRect().top;
$window.scrollBy(0, elemTop - offset);
}
} else {
$window.scrollTo(0, 0);
}
}
function scroll() {
var hash = $location.hash(), elm;
// empty hash, scroll to the top of the page
if (!hash) scrollTo(null);
// element with given id
else if ((elm = document.getElementById(hash))) scrollTo(elm);
// first anchor with given name :-D
else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);
// no element and hash == 'top', scroll to the top of the page
else if (hash === 'top') scrollTo(null);
}
if (autoScrollingEnabled) {
$rootScope.$watch(function autoScrollWatch() {return $location.hash();},
function autoScrollWatchAction(newVal, oldVal) {
// skip the initial scroll if $location.hash is empty
if (newVal === oldVal && newVal === '') return;
jqLiteDocumentLoaded(function() {
$rootScope.$evalAsync(scroll);
});
});
}
return scroll;
}];
}
//提取几段代码来分析
function $CompileProvider($provide, $$sanitizeUriProvider) {
var hasDirectives = {},
Suffix = 'Directive',
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\w\-]+)\s+(.*)$/,
CLASS_DIRECTIVE_REGEXP = /(([\w\-]+)(?:\:([^;]+))?;?)/,
ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
function parseIsolateBindings(scope, directiveName) {};
this.directive = function registerDirective(name, directiveFactory){};
this.aHrefSanitizationWhitelist = function(regexp){};
this.imgSrcSanitizationWhitelist = function(regexp){};
var debugInfoEnabled = true;
this.debugInfoEnabled = function(enabled){};
this.$get = [
'$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
'$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri',
function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse,
$controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) {};


$FilterProvider.$inject = ['$provide'];
function $FilterProvider($provide) {
var suffix = 'Filter';
function register(name, factory) {
if (isObject(name)) {
var filters = {};
forEach(name, function(filter, key) {
filters[key] = register(key, filter);
});
return filters;
} else {
return $provide.factory(name + suffix, factory);
}
}
this.register = register;
this.$get = ['$injector', function($injector) {
return function(name) {
return $injector.get(name + suffix);
};
}];
register('currency', currencyFilter);
register('date', dateFilter);
register('filter', filterFilter);
register('json', jsonFilter);
register('limitTo', limitToFilter);
register('lowercase', lowercaseFilter);
register('number', numberFilter);
register('orderBy', orderByFilter);
register('uppercase', uppercaseFilter);
}

var defaults = this.defaults = {
// transform incoming response data
transformResponse: [defaultHttpResponseTransform],
// transform outgoing request data
transformRequest: [function(d) {
return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;
}],
// default headers
headers: {
common: {
'Accept': 'application/json, text/plain, */*'
},
post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON)
},
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN'
};
this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector',
function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) {};
function $http(requestConfig){};

function $LogProvider() {
var debug = true,
self = this;
this.$get = ['$window', function($window) {
return {
log: consoleLog('log'),
info: consoleLog('info'),
warn: consoleLog('warn'),
error: consoleLog('error'),
debug: (function() {
var fn = conso
return function() {
if (debug) {
fn.apply(self, arguments);
}
};
}())
};
function formatError(arg) {
if (arg instanceof Error) {
if (arg.stack) {
arg = (arg.message && arg.stack.indexOf(arg.message) === -1)
? 'Error: ' + arg.message + '\n' + arg.stack
: arg.stack;
} else if (arg.sourceURL) {
arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line;
}
}
return arg;
}
function consoleLog(type) {
var console = $window.console || {},
logFn = console[type] || console.log || noop,
hasApply = false;
try {
hasApply = !!logFn.apply;
} catch (e) {}
if (hasApply) {
return function() {
var args = [];
forEach(arguments, function(arg) {
args.push(formatError(arg));
});
return logFn.apply(console, args);
};
}
return function(arg1, arg2) {
logFn(arg1, arg2 == null ? '' : arg2);
};
}
//初始化变量
var TTL = 10;
var $rootScopeMinErr = minErr('$rootScope');
var lastDirtyWatch = null;
var applyAsyncId = null;
//构造子函数
this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser',
function($injector, $exceptionHandler, $parse, $browser) {
//很重要的一个模型
function Scope() {
this.$id = nextUid();
this.$$phase = this.$parent = this.$$watchers =
this.$$nextSibling = this.$$prevSibling =
this.$$childHead = this.$$childTail = null;
this.$root = this;
this.$$destroyed = false;
this.$$listeners = {};
this.$$listenerCount = {};
this.$$isolateBindings = null;
}
Scope.prototype = {
constructor: Scope,
$new: function(isolate, parent){},
$watch: function(watchExp, listener, objectEquality){},
$digest: function(){},
$destroy: function(){},
$eval: function(expr, locals){},
$apply: function(expr){},
$on: function(name, listener){},
$emit: function(name, args){},
$broadcast: function(name, args){}
//还有好多好多常用东西,原来都定义在这里了呀!
}
}

step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4
})
.catch(function (error) {
// Handle any error from all above steps
})
.done();
