为加深我们对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();