angular的注入實現


angular需要對用戶的傳入函數進行靜態分析,抽取當中的依賴,才能工作。因此用戶的函數,包括控制器函數,工廠函數,服務函數與$watch回調都只是一個模板,用於取toString,真正運行的是編譯后的動態函數,有函數必須傳參。比如:

function TestCtrl($scope){
     $scope.name = "xxx"
}

$scope就是一個很復雜的類的實例,angular內部有許多類,如何決定是放這個類的實例而不是其他類的呢。這就要看這參數長得什么樣子,比如$scope肯定是作用域對象,$timeout就是定時器的。angular稱之為依賴注入,而這個最簡單的注入叫做推斷式注入。實現很簡單,取toString, 去掉函數名,去掉函數體,去掉參數名之間的注釋與逗號,剩下就是一個字符串數組。但這東西是不抗壓縮的。於是有其他兩種注入:

標記注入:在控制器函數等上面添加一個叫$inject的屬性,對應一個字符串數組,字符串不用說就是各種服務的名稱。那么angular就會在取toString進行推斷式注入前,先進行標記注入。


function TestCtrl(vm, timeout) {
    vm.friends = [{name: 'John', age: 25}, {name: 'Mary', age: 28}, {name: "Nasami", age: 30}
    timeout(function() {
        vm.friends.push({name: "add", age: 10})
    }, 1000)
}
TestCtrl.$inject = ["$scope", "$timeout"]

內聯注入:我們在使用模塊實例的factory,directive, filter或controller方法時,允許第二個傳參是一個數組,這個數組最后一個元素為函數,其他元素為它所依賴的服務名稱。這樣對框架來說,抽取依賴更方便,但對用戶來說,這傳參也太奇誕了。


angular.module('myModule', [], function($provide) {
  $provide.factory('notify', ['$window', function(win) {
    var msgs = [];
    return function(msg) {
      msgs.push(msg);
      if (msgs.length == 3) {
        win.alert(msgs.join("\n"));
        msgs = [];
      }
    };
  }]);
});

總之一句,IOC是angular為實現依賴收集被逼采取的一個非常惡心的做法,對比knockout,avalon就優雅多了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM