用原生js简单模仿angular的依赖注入
2017-05-08 23:00
441 查看
大家都知道angular 依赖注入很神奇,跟我们平常写代码的风格思维差别很大,不过仔细分析确是一个很有意思的东西,依赖注入早期也叫依赖倒置,是java中有的。废话不多少直接上例子 本帖属于原创,转载请出名出处。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>无标题文档</title> </head> <body ng-app="myApp"> <div ng-controller="firstController"> </div> <script> var angular = { injectionName: { $scope: { $$ChildScope: null, $$childHead: null, $$childTail: null, $$listenerCount: 'Object', $$listeners: 'Object', $$nextSibling: null, $$prevSibling: null, $$watchers: null, $$watchersCount: 0, $id: 2, $parent: 'Scope', }, $injector: { annotate: function (fn, strictDi, name) { }, get: function (serviceName, caller) { }, has: function (name) { }, instantiate: function (Type, locals, serviceName) { }, invoke: function (fn, self, locals, serviceName) { }, modules: 'Object', strictDi: false, }, $rootScope: { $$ChildScope: function(){}, $$applyAsyncQueue: Array[0], $$asyncQueue: Array[0], $$childHead: 'ChildScope', $$childTail: 'ChildScope', $$destroyed: false, $$isolateBindings: null, $$listenerCount: 'Object', $$listeners: 'Object', $$nextSibling: null, $$phase: null, $$postDigestQueue: Array[0], $$prevSibling: null, $$watchers: null, $$watchersCount: 0, $id: 1, $parent: null, $root: 'Scope' }, $http: function(requestConfig) { if (!isObject(requestConfig)) { throw minErr('$http')('badreq', 'Http request configuration must be an object. Received: {0}', requestConfig); } if (!isString($sce.valueOf(requestConfig.url))) { throw minErr('$http')('badreq', 'Http request configuration url must be a string or a $sce trusted object. Received: {0}', requestConfig.url); } var config = extend({ method: 'get', transformRequest: defaults.transformRequest, transformResponse: defaults.transformResponse, paramSerializer: defaults.paramSerializer, jsonpCallbackParam: defaults.jsonpCallbackParam }, requestConfig); config.headers = mergeHeaders(requestConfig); config.method = uppercase(config.method); config.paramSerializer = isString(config.paramSerializer) ? $injector.get(config.paramSerializer) : config.paramSerializer; $browser.$$incOutstandingRequestCount(); var requestInterceptors = []; var responseInterceptors = []; var promise = $q.resolve(config); // apply interceptors forEach(reversedInterceptors, function(interceptor) { if (interceptor.request || interceptor.requestError) { requestInterceptors.unshift(interceptor.request, interceptor.requestError); } if (interceptor.response || interceptor.responseError) { responseInterceptors.push(interceptor.response, interceptor.responseError); } }); promise = chainInterceptors(promise, requestInterceptors); promise = promise.then(serverRequest); promise = chainInterceptors(promise, responseInterceptors); promise = promise.finally(completeOutstandingRequest); return promise; function chainInterceptors(promise, interceptors) { for (var i = 0, ii = interceptors.length; i < ii;) { var thenFn = interceptors[i++]; var rejectFn = interceptors[i++]; promise = promise.then(thenFn, rejectFn); } interceptors.length = 0; return promise; } function completeOutstandingRequest() { $browser.$$completeOutstandingRequest(noop); } function executeHeaderFns(headers, config) { var headerContent, processedHeaders = {}; forEach(headers, function(headerFn, header) { if (isFunction(headerFn)) { headerContent = headerFn(config); if (headerContent != null) { processedHeaders[header] = headerContent; } } else { processedHeaders[header] = headerFn; } }); return processedHeaders; } function mergeHeaders(config) { var defHeaders = defaults.headers, reqHeaders = extend({}, config.headers), defHeaderName, lowercaseDefHeaderName, reqHeaderName; defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]); // using for-in instead of forEach to avoid unnecessary iteration after header has been found defaultHeadersIteration: for (defHeaderName in defHeaders) { lowercaseDefHeaderName = lowercase(defHeaderName); for (reqHeaderName in reqHeaders) { if (lowercase(reqHeaderName) === lowercaseDefHeaderName) { continue defaultHeadersIteration; } } reqHeaders[defHeaderName] = defHeaders[defHeaderName]; } // execute if header value is a function for merged headers return executeHeaderFns(reqHeaders, shallowCopy(config)); } function serverRequest(config) { var headers = config.headers; var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest); // strip content-type if data is undefined if (isUndefined(reqData)) { forEach(headers, function(value, header) { if (lowercase(header) === 'content-type') { delete headers[header]; } }); } if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) { config.withCredentials = defaults.withCredentials; } // send request return sendReq(config, reqData).then(transformResponse, transformResponse); } function transformResponse(response) { // make a copy since the response must be cacheable var resp = extend({}, response); resp.data = transformData(response.data, response.headers, response.status, config.transformResponse); return (isSuccess(response.status)) ? resp : $q.reject(resp); } }, $q:function(resolver) { if (!isFunction(resolver)) { throw $qMinErr('norslvr', 'Expected resolverFn, got \'{0}\'', resolver); } var promise = new Promise(); function resolveFn(value) { resolvePromise(promise, value); } function rejectFn(reason) { rejectPromise(promise, reason); } resolver(resolveFn, rejectFn); return promise; }, $log: console.log, $window: window, $timeout: setTimeout, $interval: setInterval, $location: window.location }, getEle: function (ele, ele2) { if (arguments.length == 1) { return document.getElementsByTagName(ele); } else { return ele.getElementsByTagName(ele2); } }, module: function (module_str) { var ele_arr = this.getEle("*"), flag = false; app_ele = null; for (var i = 0; i < ele_arr.length; i++) { if (ele_arr[i].getAttribute('ng-app') != null) { flag = true; app_ele = ele_arr[i]; break; } } if (app_ele.getAttribute('ng-app') != module_str) { throw new Error("angular ng-app " + module_str + " not registered "); } if (!flag) { throw new Error("angular ng-app not registered "); } this.tool.appEle = app_ele; return this.tool; }, tool: { controller: function (controller_str, functionName) { var ele_arr = angular.getEle(this.appEle, "*"), flag = false; app_ele = null; for (var i = 0; i < ele_arr.length; i++) { if (ele_arr[i].getAttribute('ng-controller') != null) { flag = true; app_ele = ele_arr[i]; break; } } if (app_ele.getAttribute('ng-controller') != controller_str) { throw new Error("angular ng-controller " + controller_str + " not registered "); } if (!flag) { throw new Error("angular ng-controller not registered "); } var pattern = new RegExp("\\((.| )+?\\)", "igm"); var str = functionName.toString().match(pattern) str = str[0].replace(/\s/g, ""); str = str.substring(1, str.toString().length - 1); var arr = str.split(','); var args = []; for (var i = 0; i < arr.length; i++) { args[i] = angular.injectionName[arr[i]] } functionName.apply(null, args); } } } angular.module('myApp') .controller('firstController', function ($scope,$injector) { console.log($scope); console.log($injector) }); </script> </body> </html>
相关文章推荐
- Angular之依赖注入(injector)与原生View组件
- angularjs MVC、模块化、依赖注入详解
- Angular.JS学习之依赖注入$injector详析
- AngularJS $injector 依赖注入
- 在Angular.js使用组合+依赖注入而不是继承
- AngularJS ng依赖注入的三种方式
- 【转】简单模拟angular的依赖注入
- Angularjs MVC 以及 $scope 作用域 Angularjs 模块 的 run 方法 以及依赖注入中代码压缩问题
- AngularJS $injector 依赖注入详解
- 原生js方式实现ajax,并仿jquery方式简单调用
- 模仿cnGameJs写的简单的坦克大战
- ASP.NET MVC3 + Ninject.Mvc3 依赖注入原来可以这么简单
- ASP.NET MVC 3让依赖注入实现得更简单
- 自建简单的依赖注入容器Ioc Container
- 一个简单的小程序演示Unity的三种依赖注入方式
- 依赖注入框架Autofac的简单使用
- 简单的Spring依赖注入例子~~
- ASP.NET MVC3 + Ninject.Mvc3 依赖注入原来可以这么简单
- 依赖注入框架Autofac的简单使用
- 依赖注入框架Autofac的简单使用