首页 > 语言 > JavaScript > 正文

angularjs 源码解析之injector

2024-05-06 14:52:44
字体:
来源:转载
供稿:网友

简介

injector是用来做参数自动注入的,例如

function fn ($http, $scope, aService) {}

ng在运行时会把$http, $scope, aService 自动作为参数传入进行执行。

其实很容易想明白,injector做了两件事

    缓存那些service,以后作为参数注入 分析参数列表,找到需要的参数注入

下面源码分析如何实现上面两件事情。

结构

createInjector -> createInternalInjector  return: instanceInjector

所以 createInjector() 返回的是 instanceInjector,结构如下:

{ invoke: invoke, instantiate: instantiate, get: getService, annotate: annotate, has: function(name) {  return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name); }}

源码分析

1. createInjector

function createInjector(modulesToLoad, strictDi) { strictDi = (strictDi === true); var INSTANTIATING = {},   providerSuffix = 'Provider',   path = [],   loadedModules = new HashMap([], true),   // 预先配置$provide,供loadModules中调用注册service等   providerCache = {    $provide: {      provider: supportObject(provider),      factory: supportObject(factory),      service: supportObject(service),      value: supportObject(value),      constant: supportObject(constant),      decorator: decorator     }   },   // providerInjector, instanceInjector 两个注入器   // instanceInjector对外提供service等注入,providerInjector对内提供provider获取   providerInjector = (providerCache.$injector =     createInternalInjector(providerCache, function() {      throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));     }, strictDi)),   instanceCache = {},   instanceInjector = (instanceCache.$injector =     createInternalInjector(instanceCache, function(servicename) {      var provider = providerInjector.get(servicename + providerSuffix);      return instanceInjector.invoke(provider.$get, provider, undefined, servicename);     }, strictDi)); // 加载模块 forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); }); return instanceInjector;}

2. $provide

$provide: {  provider: supportObject(provider),  factory: supportObject(factory),  service: supportObject(service),  value: supportObject(value),  constant: supportObject(constant),  decorator: decorator}

2.1 supportObject

用于包装方法,包装前的方法接受两个参数 (key, value),经过包装后的方法能支持传入object参数,即多个 key -> value。

function supportObject(delegate) { return function(key, value) {  if (isObject(key)) {   forEach(key, reverseParams(delegate));  } else {   return delegate(key, value);  } };}

2.2 provider

回顾下provider、service 和 factory的使用方式

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选