angular之$injector

背景 javascript

    其實 在 publishExternalAPI 裏面 
java

function publishExternalAPI(angular){
    extend(angular,{
        'injector': createInjector ,
    })
}

因此 當調用 angular.injector() 的時候 實際上是調用的   createInjector 方法bootstrap

對於 injector 方法c#

function createInjector(modulesToLoad,strictDi){
    // 在這裏面 建立了兩個 服務$provide   $injector 
    providerCache = {
        $provide:{
            provider:xxx,
            factory:xxx,
            service:xxx,
            value:xxx,
            constant:xxx,
            decorator:xxx
        }
    }
    
    providerInjector = (providerCache.$injector = createInternalInjector(providerCache,function(serviceName,caller)    {
        //.....
    
    }));
    
    
    instanceCache = {};
    
    instanceInjector = (instanceCache.$injector = createInternalInjector(instanceCache,function(serviceName,caller){
        var provider = providerInjector.get(serviceName + providerSuffix,caller);
        return instanceInjector.invoke(provide.$get,provide,undefined,serviceName);
    }))
    
    forEach(loadModules(modulesToLoad),function(fn){
        if(fn) instanceInjector.invoke(fn);
    })
    
    
    // 最後就返回這個對象了,咱們看下這個對象到底有多少東西
    {
        invoke:function(){},
        instantiate:function(){},
        get:function(){},
        annotate:function(){},
        has:function(){}
    }
    return instanceInjector;
    
    
    function createInternalInjector(cache,factory){
        //....
        
        return {
            invoke:invoke,
            instantiate:instantiate,
            get:getService,
            annotate:createInjector.$$annotate,
            has:function(name){
                turn provideCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
            }
        }
    }
}


對於 createInjector.$$annotate 方法,其實就是api

http://my.oschina.net/bosscheng/blog/538462 【如何在javascript中實現DI】app



對於坑爹的injector ide

var $injector = angular.injector(['ng']);

若是不添加參數的話函數

var injector = angular.injector();
// 這樣也能獲取到注入器,可是沒有和其餘模塊綁定,至關於建立了一個空的DI容器,裏面沒有任何服務,因此也沒有啥做用
console.log(injector);
console.log(injector.has('$provide')) // false 
console.log(injector.has('$injector'))  // true

正確的使用:  在建立注入器的時候,須要指定須要加載的模塊ui

var injector = angular.injector(['ng'])// ng 模塊是angular 自帶的 模塊。
//  angular.injector 能夠調用屢次,每次都返回新建的injector對象。
// 因此兩次新建的內容多是不一樣的

提供的方法有this

get

angular.module('myModule', []).

  // Teach the injector how to build a 'greeter'
  // Notice that greeter itself is dependent on '$window'
  factory('greeter', function($window) {
    // This is a factory function, and is responsible for
    // creating the 'greet' service.
    return {
      greet: function(text) {
        $window.alert(text);
      }
    };
  }).
  // New injector is created from the module.
  // (This is usually done automatically by angular bootstrap)
  var injector = angular.injector('myModule');   // createInjector 
  // Request any dependency from the injector
  var greeter = injector.get('greeter');

// 獲取 綁定的model 中的 service 方法。

greeter.greet();

invoke:

直接調用service 中的方法。

對於 invoke 方法的使用 傳遞的參數  (fn,self,locals,serviceName)

對於內部實現:

    內部調用 createInjector.$$annotate(fn,strictDi,serviceName);

    後面從service中查找這個service 對象,獲取到這個對象以後,獲取到這個service

    最後 調用fn.apply(self,args);   // args 就是真正的 service 

injector.invoke(['greeter',function(greeter){
    gerrter.greet();
}])

has

injector.has('greeter');

instantiate

create a new instance of js type,the method takes a constructor function, invoke the new 
opreator, and supplies all of the arguments to the constructor function as specified by the 
constructor annotation.

對於instantiate 的實現

function instantiate(type, locals, serviceName){
    // 新建一個對象。
    var instance = Object.create((isArray(Type) ? Type[Type.length -1]: Type ).prototype || null);
    // 直接執行這個方法 
    var returnedValue = invoke(Type,instance,locals,serviceName);
    
    return isObject(returnValue) || isFunction(returnedValue) ? returnedValue : instance;
}


annotate

return an array of service names which the function is requesting for injection,this api is
used by the injector to determine which services need to be injected into the function
when the function is invoked .there are three way in which the function can be annotated with the needed dependencies.

大概意思就是,查看這個service,或者controller 所依賴注入的東西。

其實內部就是調用了 createInjector.$$annotate 方法實現的。


注入器負責從咱們經過$provider建立的服務中建立注入的實例,只要你編寫一個帶有可注入性的參數,你能看到注入器是如何工做的,每一個angular應用有一個惟一的$injector,當應用啓動的時候他被建立出來,你能夠經過$injector 注入到任何可注入函數中獲得他

相關文章
相關標籤/搜索