最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

AngularJS之依賴注入模擬實現(xiàn)

 更新時間:2016年08月19日 08:51:40   作者:猴子  
這篇文章主要為大家詳細(xì)介紹了AngularJS依賴注入模擬實現(xiàn),感興趣的小伙伴們可以參考一下

一、概述 

AngularJS有一經(jīng)典之處就是依賴注入,對于什么是依賴注入,熟悉spring的同學(xué)應(yīng)該都非常了解了,但,對于前端而言,還是比較新穎的。 

依賴注入,簡而言之,就是解除硬編碼,達到解偶的目的。 

下面,我們看看AngularJS中常用的實現(xiàn)方式。 

方法一:推斷式注入聲明,假定參數(shù)名稱就是依賴的名稱。因此,它會在內(nèi)部調(diào)用函數(shù)對象的toString()方法,分析并提取出函數(shù)參數(shù)列表,然后通過$injector將這些參數(shù)注入進對象實例。 

如下: 

//方法一:推斷式注入聲明,假定參數(shù)名稱就是依賴的名稱。
//因此,它會在內(nèi)部調(diào)用函數(shù)對象的toString()方法,分析并提取出函數(shù)參數(shù)列表,
//然后通過$injector將這些參數(shù)注入進對象實例
injector.invoke(function($http, $timeout){
 //TODO
});

方法二:行內(nèi)注入聲明,允許我們在函數(shù)定義時,直接傳入一個參數(shù)數(shù)組,數(shù)組包含了字符串和函數(shù),其中,字符串代表依賴名,函數(shù)代表目標(biāo)函數(shù)對象。
 如下:

//方法二:行內(nèi)注入聲明,允許我們在函數(shù)定義時,直接傳入一個參數(shù)數(shù)組,
//數(shù)組包含了字符串和函數(shù),其中,字符串代表依賴名,函數(shù)代表目標(biāo)函數(shù)對象。
module.controller('name', ['$http', '$timeout', function($http, $timeout){
 //TODO
}]); 

看了上述代碼,心中有一疑問,這些是怎么實現(xiàn)的呢? 

哈哈,下面,我們就來一起模擬一下這些依賴注入方式,從而了解它們。 

二、搭建基本骨架 

依賴注入的獲取過程就是,通過字段映射,從而獲取到相應(yīng)的方法。 

故而,要實現(xiàn)一個基本的依賴注入,我們需要一個存儲空間(dependencies),存儲所需鍵值(key/value);一個注冊方法(register),用于新增鍵值對到存儲空間中;還有一個就是核心實現(xiàn)方法(resolve),通過相關(guān)參數(shù),到存儲空間中獲得對應(yīng)的映射結(jié)果。 

So,基本骨架如下: 

var injector = {
 dependencies: {},
 register: function(key, value){
 this.dependencies[key] = value;
 return this;
 },
 resolve: function(){
    
 }
};

三、完善核心方法resolve 

從我們搭建的基本骨架中,可以發(fā)現(xiàn),重點其實resolve方法,用于實現(xiàn)我們具體形式的依賴注入需求。 

首先,我們來實現(xiàn),如下形式的依賴注入:推斷式注入聲明。 

如下: 

injector.resolve(function(Monkey, Dorie){
 Monkey();
 Dorie();
}); 

要實現(xiàn)上述效果,我們可以利用函數(shù)的toString()方法,我們可以將函數(shù)轉(zhuǎn)換成字符串,從而通過正則表達式獲得參數(shù)名,即key值。 然后通過key值,在存儲空間dependencies找value值,沒找到對應(yīng)值,則報錯。 

實現(xiàn)如下: 

var injector = {
 dependencies: {},
 register: function(key, value){
 this.dependencies[key] = value;
 return this;
 },
 resolve: function(){
 var func, deps, args = [], scope = null;
 func = arguments[0];
 //獲取函數(shù)的參數(shù)名
 deps = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1].replace(/ /g, '').split(',');
 scope = arguments[1] || {};
 for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){
  if(this.dependencies[d]){
  args.push(this.dependencies[d]);
  }else{
  throw new Error('Can\'t find ' + d);
  }
 }
 func.apply(scope, args);   
 }
};

測試代碼,如下: 

<!DOCTYPE html>
 <head>
 <meta charset="utf-8"/>
 </head>
 <body>
 <script>
  var injector = {
  dependencies: {},
  register: function(key, value){
   this.dependencies[key] = value;
   return this;
  },
  resolve: function(){
   var func, deps, args = [], scope = null;
   func = arguments[0];
   //獲取函數(shù)的參數(shù)名
   deps = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1].replace(/ /g, '').split(',');
   scope = arguments[1] || {};
   for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){
   if(this.dependencies[d]){
    args.push(this.dependencies[d]);
   }else{
    throw new Error('Can\'t find ' + d);
   }
   }
   func.apply(scope, args);   
  }
  };
  //測試代碼
  injector.register('Monkey', function(){
  console.log('Monkey');
  }).register('Dorie', function(){
  console.log('Dorie');
  });
  injector.resolve(function(Monkey, Dorie){
  Monkey();
  Dorie();
  console.log('-.-');
  }); 
 </script>
 </body>
</html>

推斷式注入聲明,有個缺點,就是不能利用壓縮工具壓縮,因為我們是通過函數(shù)的參數(shù)作為依賴的,當(dāng)我們壓縮時,會將參數(shù)名改掉,參數(shù)名都變了,那肯定撲街咯。 

那么下面,我們就看看行內(nèi)注入聲明,它可以彌補這缺點。 

實現(xiàn)行內(nèi)注入聲明,如下:

 injector.resolve(['Monkey', 'Dorie', function(M, D){
 M();
 D();
}]); 

利用typeof判斷arguments[0]的類型可以辨別并獲得依賴參數(shù)和函數(shù)。 

實現(xiàn)如下: 

var injector = {
 dependencies: {},
 register: function(key, value){
 this.dependencies[key] = value;
 return this;
 },
 resolve: function(){
 var firstParams, func, deps = [], scope = null, args = [];
 firstParams = arguments[0];
 scope = arguments[1] || {};
 //獲得依賴參數(shù)
 for(var i = 0, len = firstParams.length; i < len; i++){
  var val = firstParams[i],
  type = typeof val;
  if(type === 'string'){
  deps.push(val);
  }else if(type === 'function'){
  func = val;
  }
 }
 //通過依賴參數(shù),找到關(guān)聯(lián)值
 for(i = 0, len = deps.length; i < len, d = deps[i]; i++){
  if(this.dependencies[d]){
  args.push(this.dependencies[d]);
  }else{
  throw new Error('Can\'t find ' + d);
  }
 }
 func.apply(scope || {}, args);   
 }
};

測試代碼,如下: 

<!DOCTYPE html>
 <head>
 <meta charset="utf-8"/>
 </head>
 <body>
 <script>
  var injector = {
  dependencies: {},
  register: function(key, value){
   this.dependencies[key] = value;
   return this;
  },
  resolve: function(){
   var firstParams, func, deps = [], scope = null, args = [];
   firstParams = arguments[0];
   scope = arguments[1] || {};
   //獲得依賴參數(shù)
   for(var i = 0, len = firstParams.length; i < len; i++){
   var val = firstParams[i],
    type = typeof val;
   if(type === 'string'){
    deps.push(val);
   }else if(type === 'function'){
    func = val;
   }
   }
   //通過依賴參數(shù),找到關(guān)聯(lián)值
   for(i = 0, len = deps.length; i < len, d = deps[i]; i++){
   if(this.dependencies[d]){
    args.push(this.dependencies[d]);
   }else{
    throw new Error('Can\'t find ' + d);
   }
   }
   func.apply(scope || {}, args);   
  }
  };
  //測試代碼
  injector.register('Monkey', function(){
  console.log('Monkey');
  }).register('Dorie', function(){
  console.log('Dorie');
  });
  injector.resolve(['Monkey','Dorie',function(M, D){
  M();
  D();
  console.log('-.-');
  }]); 
 </script>
 </body>
</html>

因為行內(nèi)注入聲明,是通過字符串的形式作為依賴參數(shù),so,壓縮也不怕咯。
 最后,我們將上面實現(xiàn)的兩種方法,整合到一起,就可以為所欲為啦。
 那,就合并下吧,如下: 

var injector = {
 dependencies: {},
 register: function(key, value){
 this.dependencies[key] = value;
 return this;
 },
 resolve: function(){
 var firstParams, func, deps = [], scope = null, args = [];
 firstParams = arguments[0];
 scope = arguments[1] || {};
 //判斷哪種形式的注入
 if(typeof firstParams === 'function'){
  func = firstParams;
  deps = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1].replace(/ /g, '').split(',');
 }else{
  for(var i = 0, len = firstParams.length; i < len; i++){
  var val = firstParams[i],
   type = typeof val;
  if(type === 'string'){
   deps.push(val);
  }else if(type === 'function'){
   func = val;
  }
  } 
 }
 //通過依賴參數(shù),找到關(guān)聯(lián)值
 for(i = 0, len = deps.length; i < len, d = deps[i]; i++){
  if(this.dependencies[d]){
  args.push(this.dependencies[d]);
  }else{
  throw new Error('Can\'t find ' + d);
  }
 }
 func.apply(scope || {}, args);   
 }
};

四、花絮—RequireJS之依賴注入 

依賴注入并非在AngularJS中有,倘若你使用過RequireJS,那么下面這種形式,不會陌生吧:

 require(['Monkey', 'Dorie'], function(M, D){
 //TODO 
}); 

通過,上面我們一步步的模擬AngularJS依賴注入的實現(xiàn),想必,看到這,你自己也會豁然開朗,換湯不換藥嘛。 

模擬實現(xiàn)如下: 

var injector = {
 dependencies: {},
 register: function(key, value){
 this.dependencies[key] = value;
 return this;
 },
 resolve: function(deps, func, scope){
 var args = [];
 for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){
  if(this.dependencies[d]){
  args.push(this.dependencies[d]);
  }else{
  throw new Error('Can\'t resolve ' + d);
  }
 }
 func.apply(scope || {}, args);
 }
};

測試代碼如下: 

<!DOCTYPE html>
 <head>
 <meta charset="utf-8"/>
 </head>
 <body>
 <script>
  var injector = {
  dependencies: {},
  register: function(key, value){
   this.dependencies[key] = value;
   return this;
  },
  resolve: function(deps, func, scope){
   var args = [];
   for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){
   if(this.dependencies[d]){
    args.push(this.dependencies[d]);
   }else{
    throw new Error('Can\'t resolve ' + d);
   }
   }
   func.apply(scope || {}, args);
  }
  };
  //測試代碼  
  injector.register('Monkey', function(){
  console.log('Monkey');
  }).register('Dorie', function(){
  console.log('Dorie');
  });
  injector.resolve(['Monkey', 'Dorie'], function(M, D){
  M();
  D();
  console.log('-.-');
  }); 
 </script>
 </body>
</html>

五、參考 

1、AngularJS應(yīng)用開發(fā)思維之3:依賴注入 
2、Dependency injection in JavaScript

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • AngularJS ng-app 指令實例詳解

    AngularJS ng-app 指令實例詳解

    本文主要介紹AngularJS ng-app 指令,這里整理了ng-app指令的一些資料,并附實例代碼,有需要的小伙伴可以參考下
    2016-07-07
  • AngularJS中transclude用法詳解

    AngularJS中transclude用法詳解

    這篇文章主要介紹了AngularJS中transclude用法,詳細(xì)分析了transclude的具體功能、使用技巧與相關(guān)注意事項,需要的朋友可以參考下
    2016-11-11
  • 對angular2中的ngfor和ngif指令嵌套實例講解

    對angular2中的ngfor和ngif指令嵌套實例講解

    今天小編就為大家分享一篇對angular2中的ngfor和ngif指令嵌套實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • AngularJS入門教程之迭代器過濾詳解

    AngularJS入門教程之迭代器過濾詳解

    本文主要介紹AngularJS 迭代器過濾,這里提供了詳細(xì)的知識資料,并附示例代碼,有需要的小伙伴可以參考下
    2016-08-08
  • 在 Angular6 中使用 HTTP 請求服務(wù)端數(shù)據(jù)的步驟詳解

    在 Angular6 中使用 HTTP 請求服務(wù)端數(shù)據(jù)的步驟詳解

    本文分步驟給大家介紹了在 Angular6 中使用 HTTP 請求服務(wù)端數(shù)據(jù)的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • angular4自定義表單控件[(ngModel)]的實現(xiàn)

    angular4自定義表單控件[(ngModel)]的實現(xiàn)

    這篇文章主要介紹了angular4自定義表單控件[(ngModel)]的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • 詳解angular2如何手動點擊特定元素上的點擊事件

    詳解angular2如何手動點擊特定元素上的點擊事件

    這篇文章主要介紹了詳解angular2如何手動點擊特定元素上的點擊事件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • angular中的cookie讀寫方法

    angular中的cookie讀寫方法

    本篇文章主要介紹了angular中的cookie讀寫方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Angular表單驗證實例詳解

    Angular表單驗證實例詳解

    這篇文章主要介紹了angular表單驗證的相關(guān)知識,angular來驗證可以定義樣式的,下文通過代碼給大家實例介紹下,需要的朋友可以參考下
    2016-10-10
  • AngularJS入門示例之Hello World詳解

    AngularJS入門示例之Hello World詳解

    這篇文章主要介紹了AngularJS入門示例之Hello World,較為詳細(xì)的分析了AngularJS程序的原理及Hello World程序的創(chuàng)建步驟,需要的朋友可以參考下
    2017-01-01

最新評論

泸定县| 望江县| 平远县| 杭州市| 长武县| 泰兴市| 黄平县| 长治市| 延边| 农安县| 浙江省| 本溪市| 连云港市| 大埔县| 江西省| 张家口市| 永安市| 甘泉县| 韶山市| 潢川县| 宝应县| 满洲里市| 武隆县| 阜康市| 绩溪县| 金华市| 全南县| 恭城| 泽州县| 三河市| 宜黄县| 大田县| 岳池县| 华蓥市| 肥乡县| 阿图什市| 同仁县| 门头沟区| 浮山县| 金昌市| 西华县|