国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

AngularJs 入門(二)--模塊

Yangyang / 427人閱讀

摘要:同名模塊已經(jīng)初始化的模塊保存在一個(gè)叫的緩存對(duì)象中,是模塊名,是模塊對(duì)象。調(diào)用注入器的方法執(zhí)行模塊的所有方法。檢查該注入器中是否存在指定的服務(wù)。如果是數(shù)組,最后一個(gè)必須是的構(gòu)造函數(shù),前面的就是構(gòu)造函數(shù)的參數(shù)名。

模塊

模塊是指寫Angular應(yīng)用的代碼片段,這樣可以使代碼分離開來(lái),因此代碼會(huì)更好維護(hù),可讀和測(cè)試。還可以在module里定義代碼依賴關(guān)系,可以調(diào)用一個(gè)模塊,再在代碼中定義這個(gè)模塊依賴于另外兩個(gè)。

angular模塊通過angular.module(name,requires, configFn)方法生成:
1>參數(shù)name是模塊名稱;
2>參數(shù)requires表示依賴模塊數(shù)組。
如果不設(shè)置requires參數(shù),調(diào)用angular.module(name)方法表示獲取這個(gè)模塊;如果確定新模塊沒有依賴關(guān)系,必須設(shè)置requires為空數(shù)[arguments];
如果不是字符串,則必須是方法(或數(shù)組格式的方法),那么,這個(gè)方法就代表了一個(gè)模塊。
3>參數(shù)configFn是方法或數(shù)組,負(fù)責(zé)在模塊初始化時(shí)做一些配置,如果是數(shù)組,最后一個(gè)元素必須是方法。
方法configFn并不是在執(zhí)行angular.module()的時(shí)候立即執(zhí)行,而是當(dāng)這個(gè)模塊被第一次使用時(shí),由注入器調(diào)用執(zhí)行。同時(shí),查看方法configFn中的this就會(huì)發(fā)現(xiàn),這個(gè)this在瀏覽器中指向的是window,而不是module。而且,方法configFn只會(huì)執(zhí)行一次,因此同一個(gè)angular模塊不會(huì)重復(fù)配置。
實(shí)例:
angular.module("MetronicApp")
    .controller("AppController", 
    ["$scope", "$rootScope", "AppCommonService", "DictService", 
    function ($scope, $rootScope, AppCommonService, DictService) {
        // code
    });
}]);


AngularJS允許我們使用angular.module()方法來(lái)聲明模塊,這個(gè)方法能夠接受兩個(gè)參數(shù), 第一個(gè)是模塊的名稱,第二個(gè)是依賴列表,也就是可以被注入到模塊中的對(duì)象列表。
同名模塊

已經(jīng)初始化的angular模塊保存在一個(gè)叫modules的緩存對(duì)象中,key是模塊名,value是模塊對(duì)象。所以,定義一個(gè)同名的模塊,等于覆蓋之前的模塊。

服務(wù)注入

angular模塊只保留服務(wù)的定義,現(xiàn)在再來(lái)理解服務(wù)是如何加入注入器的。

 模塊定義服務(wù)、服務(wù)提供商;
 注入器根據(jù)模塊依賴關(guān)系加載模塊,實(shí)例化所有服務(wù)提供商;
 應(yīng)用需要服務(wù),注入器根據(jù)服務(wù)名尋找服務(wù)提供商,服務(wù)提供商實(shí)例化服務(wù)。

以上只是理論,現(xiàn)在從代碼層面來(lái)看Angular是如何實(shí)現(xiàn)的。

每個(gè)angular模塊內(nèi)置有三個(gè)數(shù)組,invokeQueue保存如何注入服務(wù)提供商和值的信息;configBlocks保存模塊的配置信息;runBlocks保存這個(gè)模塊的執(zhí)行信息。模塊被使用的時(shí)候,注入器根據(jù)invokeQueue中的信息,實(shí)例化服務(wù)提供商;根據(jù)configBlocks中的信息對(duì)服務(wù)提供商做一些額外的處理;根據(jù)runBlocks中提供的信息,調(diào)用前面的服務(wù)提供商提供的服務(wù)執(zhí)行模塊需要完成的工作。
angular模塊提供了很多方法來(lái)填充這三個(gè)數(shù)組,比如config()、run()等。三個(gè)數(shù)組的元素也是數(shù)組,具體元素格式參考后面的說(shuō)明。
以下是源碼,可以清楚看到每個(gè)模塊所要依賴的服務(wù)和運(yùn)行機(jī)制,稍后詳細(xì)介紹。

   var angular = ensure(window, "angular", Object);
  angular.$$minErr = angular.$$minErr || minErr;
  return ensure(angular, "module", function() {
    var modules = {};
    return function module(name, requires, configFn) {
      var assertNotHasOwnProperty = function(name, context) {
        if (name === "hasOwnProperty") {
          throw ngMinErr("badname", "hasOwnProperty is not a valid {0}     name", context);
        }
      };

      assertNotHasOwnProperty(name, "module");
      if (requires && modules.hasOwnProperty(name)) {
        modules[name] = null;
      }
      return ensure(modules, name, function() {
        if (!requires) {
          throw $injectorMinErr("nomod", "Module "{0}" is not available! You either misspelled " +
         "the module name or forgot to load it. If registering a module ensure that you " +
         "specify the dependencies as the second argument.", name);
        }

    /** @type {!Array.>} */
    var invokeQueue = [];

    /** @type {!Array.} */
    var configBlocks = [];

    /** @type {!Array.} */
    var runBlocks = [];

    var config = invokeLater("$injector", "invoke", "push", configBlocks);

    /** @type {angular.Module} */
    var moduleInstance = {
      // Private state
      _invokeQueue: invokeQueue,
      _configBlocks: configBlocks,
      _runBlocks: runBlocks,
      requires: requires,
      name: name,
      provider: invokeLaterAndSetModuleName("$provide", "provider"),
      factory: invokeLaterAndSetModuleName("$provide", "factory"),
      service: invokeLaterAndSetModuleName("$provide", "service"),
      value: invokeLater("$provide", "value"),
      constant: invokeLater("$provide", "constant", "unshift"),
      decorator: invokeLaterAndSetModuleName("$provide", "decorator"),
      animation: invokeLaterAndSetModuleName("$animateProvider", "register"),
      filter: invokeLaterAndSetModuleName("$filterProvider", "register"),
      controller: invokeLaterAndSetModuleName("$controllerProvider", "register"),
      directive: invokeLaterAndSetModuleName("$compileProvider", "directive"),
      config: config,
      run: function(block) {
        runBlocks.push(block);
        return this;
      }
    };
    if (configFn) {
      config(configFn);
    }
    return moduleInstance;
    function invokeLater(provider, method, insertMethod, queue) {
      if (!queue) queue = invokeQueue;
      return function() {
        queue[insertMethod || "push"]([provider, method, arguments]);
        return moduleInstance;
      };
    }
    function invokeLaterAndSetModuleName(provider, method) {
      return function(recipeName, factoryFunction) {
        if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
        invokeQueue.push([provider, method, arguments]);
        return moduleInstance;
      };
    }
  });
};

});

調(diào)用隊(duì)列 – invokeQueue

數(shù)組元素為[‘provider’, ‘method’, arguments]。
舉例– 添加一個(gè)Controller:

angular.module("ngAppDemo",[])        
.controller("ngAppDemoController",function($scope) {       
      $scope.a= 1;      
      $scope.b = 2;      
});  

這段代碼等于:

invokeQueue.push(["$controllerProvider","register",
    ["ngAppDemoController", function(){
    //code

}]]);  

注入器根據(jù)這個(gè)信息,就會(huì)調(diào)用$controllerProvider的register方法注冊(cè)一個(gè)ngAppDemoController。

配置隊(duì)列 – configBlocks

元素格式為["$injector", "invoke", arguments]。

運(yùn)行隊(duì)列 – runBlocks

元素要求是方法,或者是數(shù)組,數(shù)組最后一個(gè)元素是方法。

angular模塊實(shí)例屬性和方法
屬性
requires
表示模塊的依賴數(shù)組,即angular.module方法的requires參數(shù)。
name
模塊的名字。
_invokeQueue、_configBlocks、_runBlocks
分別對(duì)應(yīng)invokeQueue、configBlocks、runBlocks。
方法

模塊的以下方法最后全部會(huì)返回模塊實(shí)例本身,形成執(zhí)行鏈。

animation()
調(diào)用這個(gè)方法表示這個(gè)模塊將在$animateProvider中注冊(cè)一個(gè)動(dòng)畫服務(wù)。
原理:在invokeQueue尾部插入["$animateProvider", "register", arguments]。
config()
調(diào)用這個(gè)方法,表示給這個(gè)模塊追加一個(gè)配置方法。
原理:在configBlocks尾部插入["$injector","invoke", arguments]。
constant()
調(diào)用這個(gè)方法表示這個(gè)模塊將給默認(rèn)的$provider注冊(cè)一個(gè)常量。
原理:在invokeQueue首部插入["$provide", "constant", arguments]。
controller()
調(diào)用這個(gè)方法表示模塊將在$controllerProvider中注冊(cè)一個(gè)控制器。
原理:在invokeQueue尾部插入["$controllerProvider", "register", arguments]。
directive()
調(diào)用這個(gè)方法表示這個(gè)模塊將在$compileProvider中注冊(cè)一個(gè)指令。
原理:在invokeQueue尾部插入["$compileProvider", "directive", arguments]。
factory()
調(diào)用這個(gè)方法表示這個(gè)模塊中將生成一個(gè)服務(wù)工廠(隱式創(chuàng)建一個(gè)了服務(wù)提供商)。
原理:在invokeQueue尾部插入["$provide", "factory", arguments]。
filter()
調(diào)用這個(gè)方法表示這個(gè)模塊將在$filterProvider中注冊(cè)一個(gè)過濾器。
原理:在invokeQueue尾部插入["$filterProvider", "register", arguments]。
provider()
調(diào)用這個(gè)方法表示這個(gè)模塊將添加一個(gè)服務(wù)提供商。
原理:在invokeQueue尾部插入["$provide", "provider", arguments]。
run(block)
調(diào)用這個(gè)方法表示這個(gè)模塊將執(zhí)行某個(gè)功能塊,block可以是方法,也可以是數(shù)組。
原理:在invokeQueue尾部插入block。
service()
調(diào)用這個(gè)方法表示這個(gè)模塊將注冊(cè)一個(gè)服務(wù)(隱式創(chuàng)建了一個(gè)服務(wù)提供商)。
原理:在invokeQueue尾部插入["$provide", "service", arguments]。
value()
調(diào)用這個(gè)方法表示這個(gè)模塊將注冊(cè)一個(gè)變量(隱式創(chuàng)建了一個(gè)服務(wù)提供商)。
原理:在invokeQueue尾部插入["$provide", "value", arguments]。
服務(wù)注入器(Service Injector) & 服務(wù)提供商(Service Provider)

在Angular中,服務(wù)可能是對(duì)象、方法、或者一個(gè)常量值。服務(wù)由服務(wù)提供商創(chuàng)建,而服務(wù)提供商由注入器統(tǒng)一管理。當(dāng)我們需要某個(gè)服務(wù)的時(shí)候,注入器負(fù)責(zé)根據(jù)服務(wù)名尋找相應(yīng)的服務(wù)提供商,然后由服務(wù)提供商的$get()生產(chǎn)工廠創(chuàng)建服務(wù)實(shí)例。因此,服務(wù)提供商必須有一個(gè)$get()方法,這個(gè)方法就是服務(wù)創(chuàng)建單例工廠。

背后原理:注入器中的Providers和Services各自通過一個(gè)Map對(duì)象保存在緩存(分別對(duì)應(yīng)providerCache和instanceCache)中,只不過Providers的key是serviceName + “Provider”,而Services的key是serviceName。
服務(wù)提供商-Provider

Provider即服務(wù)提供商,必須有一個(gè)$get()方法,$get()的返回值是Provider在注入器中實(shí)際的服務(wù)。
注入器

創(chuàng)建注入器的方法只在bootstrap()方法中被調(diào)用過,也就是說(shuō),每一個(gè)angular應(yīng)用對(duì)應(yīng)一個(gè)注入器。
注入過程

注入器由angular.injector(modulesToLoad, isStrictDi)方法創(chuàng)建,在angular中其實(shí)為createInjector方法。參數(shù)modulesToLoad是數(shù)組,元素格式為以下之一:

‘module’,模塊的名稱。
[‘service1’, ‘service2’, fn]。
fn,方法的返回值必須仍然是方法。

方法angular.injector()的執(zhí)行過程:

遍歷modulesToLoad,根據(jù)moduleName尋找或生成相應(yīng)的模塊。

調(diào)用模塊invokeQueue中的所有方法,這一步的目的是創(chuàng)建必需的服務(wù)。

調(diào)用模塊configBlocks中的所有方法,目的是用已有的服務(wù)配置這個(gè)模塊。

調(diào)用注入器的invoke()方法執(zhí)行模塊runBlocks的所有方法。

返回服務(wù)注入器實(shí)例。

不是所有模塊都是對(duì)象,如果模塊本身是方法或者是數(shù)組(最后一個(gè)元素必須是方法),則運(yùn)行這個(gè)方法、或數(shù)組的最后一個(gè)方法,相當(dāng)于直接進(jìn)入了第四步。
注入器與bootstrap的關(guān)系

創(chuàng)建注入器的方法在angular.js中只在bootstrap()方法中被調(diào)用過,也就是說(shuō),每一個(gè)angular應(yīng)用對(duì)應(yīng)一個(gè)注入器。
注入器方法

在providerCache中和instanceCache中分別內(nèi)置有一個(gè)$injector對(duì)象,分別負(fù)責(zé)給模塊注入服務(wù)提供商和為方法注入服務(wù)。一般我們只談?wù)搃nstanceCache中的$injector對(duì)象,因?yàn)閜roviderCache和它的$injector是私有的,只在Angular內(nèi)部代碼使用。

比如,執(zhí)行模塊調(diào)用隊(duì)列、配置隊(duì)列中的方法時(shí)注入的是服務(wù)提供商,而當(dāng)調(diào)用運(yùn)行隊(duì)列中的方法時(shí),注入的是服務(wù)。
$injector.invoke(fn, self, locals, serviceName)

執(zhí)行方法fn。locals是可選參數(shù),是對(duì)象,表示局部變量。self是fn中的this。

最后一個(gè)參數(shù)serviceName是可選參數(shù),表示在哪個(gè)服務(wù)中調(diào)用了fn方法,用于錯(cuò)誤信息顯示,沒有處理邏輯。
$injector.instantiate(Type, locals, serviceName)

l 如果參數(shù)Type為方法,根據(jù)Type的prototype創(chuàng)建一個(gè)實(shí)例(通過Object.create方法創(chuàng)建),如果Type是數(shù)組,使用最后一個(gè)元素的prototype。

l 參數(shù)Locals是當(dāng)Type方法的參數(shù)出現(xiàn)在locals對(duì)象中的時(shí)候,取locals[arg]的值重新作為Type的參數(shù)。如果locals中沒有,則等價(jià)于調(diào)用get(arg,serviceName)獲取service作為新的參數(shù)。

實(shí)例化過程可以簡(jiǎn)單概括為

Type.apply(Object.create(Type.prototype),locals[argName]|| get(argName, serviceName))。  

注意:實(shí)例化出來(lái)的不一定是對(duì)象,也可能是方法。

最后一個(gè)參數(shù)serviceName是可選參數(shù),表示在哪個(gè)服務(wù)中實(shí)例化了Type,用于錯(cuò)誤信息顯示,沒有處理邏輯。
$injector.get(name, caller)

從注入器中獲取一個(gè)服務(wù)實(shí)例。

參數(shù)name是服務(wù)的名稱。參數(shù)caller也是字符串,表示調(diào)用這個(gè)服務(wù)的是哪個(gè)方法,用于錯(cuò)誤信息提示,沒有處理邏輯。
$injector.annotate(fn,strictDi )

返回?cái)?shù)組,數(shù)組的元素是fn方法需要注入的依賴服務(wù)。

在嚴(yán)格模式下,方法的依賴注入必須使用顯示的注解加入,也就是說(shuō)通過fn.$injector能夠獲取這個(gè)方法的依賴注入。

參數(shù)name是可選的,用于錯(cuò)誤顯示,沒有處理邏輯。

方法annotate()也可以接受數(shù)組,數(shù)組的最后一個(gè)參數(shù)一定是fn,前面的元素則是依賴。
$injector.has(name)

檢查該注入器中是否存在指定的服務(wù)。
Provider方法

注入器的providerCache中內(nèi)置有一個(gè)$provider對(duì)象,這是注入器的默認(rèn)服務(wù)提供商,$provider有六個(gè)固定的方法。這幾個(gè)方法的作用主要是為注入器添加其他服務(wù)提供商。

注意:

以下所有方法的name參數(shù)不需要以“Provider”結(jié)尾,因?yàn)閜rovider()方法會(huì)默認(rèn)把這個(gè)后綴加上。
以下任何一個(gè)方法不做同名判斷,因此,如果出現(xiàn)同名,后者將覆蓋前者。

$provider.provide(name, provider)

參數(shù)provider可以是方法或數(shù)組,也可以是對(duì)象。

l 如果是方法,則是provider的構(gòu)造函數(shù)。調(diào)用注入器的instantiate()方法,生成一個(gè)provider實(shí)例,并以name為key保存在注入器的providerCache中。

l 如果是數(shù)組,最后一個(gè)必須是provider的構(gòu)造函數(shù),前面的就是構(gòu)造函數(shù)的參數(shù)名。之后的原理和provider是方法的情形相同。

l 如果是對(duì)象,說(shuō)明這個(gè)provider已經(jīng)被實(shí)例化了,只需有$get()方法即可。
$provider.factory(name, factoryFn, enforce)

使用$provider.provide()一般需要定義一個(gè)Provider類,如果不想定義Provider類,而是直接定義服務(wù)工廠,就可以使用這個(gè)方法。

背后原理:首先生成一個(gè)匿名對(duì)象,這個(gè)對(duì)象的$get屬性就是factoryFn(enforce為false的情況下),然后把這個(gè)匿名對(duì)象作為$provider.provide()方法的第二個(gè)參數(shù)。所以,factoryFn其實(shí)依然是綁定在一個(gè)provider上的。
$provider.service(name, constructor)

調(diào)用injector.instantiate()方法,利用參數(shù)constructor生成service實(shí)例,參數(shù)name是這個(gè)service的名稱。

眾所周知,service由provider提供,那這個(gè)方法是怎么回事?原理:Angular首先根據(jù)constructor生成一個(gè)factoryFn,然后調(diào)用$provider.factory(name, factoryFn)。所以其實(shí)還是生成了一個(gè)provider。

舉例:

$provider.service("filter", constructor)

等于創(chuàng)建了一個(gè)filter服務(wù)實(shí)例,并且在providerCache中保存了一個(gè)名稱為“filterProvider”的服務(wù)提供商。
$provider.value(name, value)

這個(gè)方法實(shí)際調(diào)用injector.factory(name,valueFn(value), false)方法實(shí)現(xiàn)。所以其實(shí)等于創(chuàng)建一個(gè)只提供值的服務(wù)提供商。
$provider.constant(name, value)

這個(gè)方法直接在providerCache中添加一個(gè)屬性實(shí)現(xiàn)。
$provider.decorate(serviceName, decorFn)

修改舊的服務(wù),改為執(zhí)行decorFn方法,并把servcieName原來(lái)的服務(wù)作為一個(gè)參數(shù),參數(shù)名為$delegate。等價(jià)于一個(gè)靜態(tài)代理。

背后原理:首先根據(jù)seviceName找到Provider,然后修改provider的$get屬性。

angular內(nèi)置模塊

ngLocale - 本地化模塊

angular.module("ngLocale",[]).provider("$locale", $LocaleProvider);

結(jié)果是invokeQueue.push(["$provide", "provider",["$locale", $LocaleProvider]]);

ng

angular.module("ng",["ngLocale"]).config(["$provide", function(){}]);

結(jié)果是configBlocks.push(["$injector", "invoke",["$provide", function(){}]])。
三個(gè)固定模塊

每個(gè)使用bootstrap(element, modules, config)生成的應(yīng)用,注入器中有三個(gè)固定的模塊:

第一個(gè)模塊是"ng"。
第二個(gè)模塊是[‘$provider’,fn],它的作用是把根元素element作為變量保存在$provider中。
第三個(gè)模塊是[‘$compileProvider’,fn],它的作用是根據(jù)config.debugInfoEnabled調(diào)用 $conpileProvider.debugInfoEnabled(true)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92593.html

相關(guān)文章

  • AngularJs 入門(一)--前言

    摘要:入門一前言目前來(lái)說(shuō)相對(duì)于現(xiàn)在流行的高版本以及來(lái)說(shuō)實(shí)屬是老套的前端框架了,當(dāng)然這都不重要,沒有完美的框架,只有不斷優(yōu)化的代碼。通過使用我們稱為指令的結(jié)構(gòu),讓瀏覽器能夠識(shí)別新的語(yǔ)法。使用作為輸入,而不是字符串,是區(qū)別于其它的框架的最大原因。 AngularJs 入門(一) 前言 AngularJs目前來(lái)說(shuō)相對(duì)于現(xiàn)在流行的高版本ng2、ng4,以及Vue2.0、React來(lái)說(shuō)實(shí)屬是老套的前...

    wenyiweb 評(píng)論0 收藏0
  • 前端資源系列(4)-前端學(xué)習(xí)資源分享&前端面試資源匯總

    摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...

    princekin 評(píng)論0 收藏0
  • angular - 收藏集 - 掘金

    摘要:如何在中使用動(dòng)畫前端掘金本文講一下中動(dòng)畫應(yīng)用的部分。與的快速入門指南推薦前端掘金是非常棒的框架,能夠創(chuàng)建功能強(qiáng)大,動(dòng)態(tài)功能的。自發(fā)布以來(lái),已經(jīng)廣泛應(yīng)用于開發(fā)中。 如何在 Angular 中使用動(dòng)畫 - 前端 - 掘金本文講一下Angular中動(dòng)畫應(yīng)用的部分。 首先,Angular本生不提供動(dòng)畫機(jī)制,需要在項(xiàng)目中加入Angular插件模塊ngAnimate才能完成Angular的動(dòng)畫機(jī)制...

    AlexTuan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<