用原生js简单模仿angular的依赖注入
大家都知道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>
用原生js简单模仿angular的依赖注入的更多相关文章
- 【转】简单模拟angular的依赖注入
原文:http://www.oschina.net/code/snippet_1181081_35136 代码片段 var angular = function(){}; Object.defineP ...
- angular 实现依赖注入
1:首先获取module对象var myAppModule = angular.module('myApp', []); 2:定义对象(类似spring中xml声明bean对象<bean id= ...
- 原生JS简单的无缝自动轮播
最近在不断的加强巩固js.在学习jq和vue之后发现很多东西其实都是不明所以,有些底层的东西自己不懂,到头来也只是一昧的使用,一直在用别人的东西,对自己的成长帮助也不大. 万丈高楼平地起,基础打扎实了 ...
- 原生js简单调用百度翻译API实现的翻译工具
先来个在线demo: js翻译工具 或者百度搜索js简单调用百度翻译API工具(不过有个小小的界面显示bug,我想细心的人应该会发现) 或者直接前往该网址:js翻译工具 或者前往我的github:gi ...
- 原生js简单实现拖拽效果
实现弹窗拖拽效果的原理是:按下鼠标并移动——拖拽移动物体,抬起鼠标——停止移动.主要触发三个事件:onmousedown.onmousemove以及onmouseup: 首先搭建结构:一个宽350px ...
- Angular的依赖注入(依赖反转)原理说明
依赖注入(依赖反转)意思是由函数决定要引入什么样的依赖: let mod = angular.module('test',[]); mod.controller('test_c',function($ ...
- angular关于依赖注入
<html> <head> <title>Angular JS Forms</title> </head> <body> < ...
- Angular 4 依赖注入
一.依赖注入 1. 创建工程 ng new myangular 2. 创建组件 ng g componet product1 3. 创建服务 ng g service shared/product 如 ...
- 手把手原生js简单轮播图
在团队带人,突然被人问到轮播图如何实现,进入前端领域有一年多了,但很久没自己写过,一直是用大牛写的插件,今天就写个简单的适合入门者学习的小教程.当然,轮播图的实现原理与设计模式有很多种,我这里讲的是用 ...
随机推荐
- maven 灵活构建
灵活构建 项目的构建根据不同的情况可能需要有一定的差异,比如编译级别.依赖.打包的属性文件等在不同的运行环境中可能需要有不同的值.为了实现灵活构建,Maven内置了三个特性: 属性:在POM中通过${ ...
- 敏捷开发SCM
敏捷的目标:自组织,提高交付质量和交付速度:敏捷中实现拥抱变化是通过迭代增量实现的:所谓的迭代是循环,循环一种机制和模式,增量则是价值的增加,迭代增量,就是通过每次工作流程的循环实现业务价值的提升:那 ...
- python selenium Chrome模拟手机浏览器(十七)
在做移动端页面测试时可以利用Chrome mobile emulation 辅助完成页面的适配问题,但是目前手机市场上的型号居多我们也没有办法通过人工的模式一一的去适配,所以这里考虑到通过自动化的模式 ...
- Btrace 拦截时机
Kind.ENTRY 入口,默认值 Kind.RETURN: 返回 Kind.THROW: 异常 Kind.Line: 行 一.返回时拦截 package com.example.monitor_t ...
- Python 标准库笔记(1) — String模块
原文出处: j_hao104 String模块包含大量实用常量和类,以及一些过时的遗留功能,并还可用作字符串操作. 1. 常用方法 常用方法 描述 str.capitalize() 把字符串的首字母大 ...
- android studio 升级到3.3.1后,提示程序包不存在
android studio 升级到3.3.1后,提示程序包不存在 原因 主Module--A 引用了其他Moduel--B里的jar库, 只需要把B的dependencies改成如下(implent ...
- 视频信号中xyz的提取
视频信号中xyz的提取 `timescale 1ns / 1ps /////////////////////////////////////////////////////////////////// ...
- 群晖NAS同步文件,防止Mac OS X自动休眠的办法
背景: NAS drive同步文件到移动硬盘,需要消耗很长时间.但长时间不动电脑,mac又会自动关闭所有application,进入休眠模式,导致同步任务被终止. 使用系统的节能设置配置也没能成功关闭 ...
- Win7下,nginx默认80端口被System占用,造成nginx启动报错
在win7 32位旗舰版下,启动1.0.8版本nginx,显示如下错误: 2012/04/02 13:55:59 [emerg] 7864#2376: bind() to 0.0.0.0:80 fai ...
- [UE4]瞬移前后屏幕亮度变化,Get Player Camera Manager.Start Camera Fade
From Alpha:开始的颜色透明度 To Alpha:结束的颜色透明度 Duration:过渡所使用的时间(单位:秒) Color:屏幕变化的颜色 Hold when finished:过渡时间结 ...