zoukankan      html  css  js  c++  java
  • 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("
    "));
            msgs = [];
          }
        };
      }]);
    });
    

    总之一句,IOC是angular为实现依赖收集被逼采取的一个非常恶心的做法,对比knockout,avalon就优雅多了。

  • 相关阅读:
    JS/jquery实现鼠标控制页面元素显隐
    【干货】十分钟读懂浏览器渲染流程
    【干货分享】程序员常访问的国外技术交流网站汇总
    jquery源码分析(七)——事件模块 event(二)
    jquery源码分析(五)——Deferred 延迟对象
    对于BFC(block format context)理解
    前端开发神器之chrome 综述
    重新认识面向对象
    DOMContentLoaded 与onload区别以及使用
    HTML5本地存储——Web SQL Database与indexedDB
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/3175759.html
Copyright © 2011-2022 走看看