博客
关于我
AngularJS之Dependency Injection(五)
阅读量:412 次
发布时间:2019-03-05

本文共 3115 字,大约阅读时间需要 10 分钟。

AngularJS 依赖注入实战:从装饰器到 $injector

在 AngularJS 开发中,依赖注入是核心机制之一。它允许我们将应用的各个部分(如服务、过滤器、指令等)以声明方式注入到控制器或其他地方,从而实现松耦合和可测试的应用架构。本文将从装饰器(decorator)谈起,深入探讨如何基于 Angular 提供的依赖注入机制来构建和管理应用组件。


装饰器:修改服务而无需修改代码

在 Angular 中,装饰器是一种强大的工具,它允许我们在服务、过滤器或指令被注册之前对它们进行修改。这意味着即使源代码无法修改,我们仍然可以通过装饰器对其进行定制和扩展。

最常见的装饰器用途之一是对日志服务进行自定义。在 Angular 的默认配置中,$log 服务是一个简单的日志记录器。通过装饰器,我们可以在其上添加额外功能,例如在每次日志记录时打印额外信息。

以下是一个典型的装饰器示例:

angular.module('myApp', []).config(['$provide', function($provide) {    $provide.decorator('$log', [        '$delegate',         function($delegate) {            var originalWarn = $delegate.warn;            $delegate.warn = function decoratedWarn(msg) {                msg = 'Decorated Warn: ' + msg;                originalWarn.apply($delegate, arguments);            };            return $delegate;        }    ]);}]);

在这个示例中,装饰器通过拦截 $log 服务的 warn 方法,向其添加了额外的功能。每当 warn 被调用时,会在消息前添加一个固定的字符串。这样,即使不修改源代码,我们也可以在日志输出时添加自定义信息。


通过 $injector 管理组件

在 Angular 应用中,$injector 服务是依赖注入的核心。它负责查找和注入应用中定义的服务、过滤器和指令。通过 $injector,我们可以不仅注入基本服务,还可以动态获取模块中的组件和资源。

$injector 提供了多种方法来管理组件,例如:

  • annotate:获取指定函数的参数注释。
  • get:获取指定服务名称的服务实例。
  • invoke:调用函数并注入所需参数。

以下是一个使用 $injector 注注的示例:

testApp.controller("indexController", function ($scope, $log, $injector) {    var counter = 0;    var logClick = function ($log, $exceptionHandler, message) {        if (counter == 0) {            $log.log(message);            counter++;        } else {            $exceptionHandler("已经点击过了");        }    };    $scope.handleClick = function () {        var deps = $injector.annotate(logClick);        for (var i = 0; i < deps.length; i++) {            console.log("依赖项: " + deps[i]);        }    };});

在这个示例中,$injector.annotate(logClick) 返回了 logClick 函数的所有依赖项。通过遍历这些依赖项,我们可以详细了解哪些服务被注入到函数中。


获取服务通过 $injector

除了通过注入函数参数获取服务,$injector 还提供了获取服务实例的方法。例如,可以通过 $rootElement.injector() 获取根元素所在模块的 $injector

以下是一个动态注入服务的示例:

testApp.controller("indexController", function ($scope, $log, $rootElement) {    var counter = 0;    var logClick = function ($log, $exceptionHandler, message) {        if (counter == 0) {            $log.log(message);            counter++;        } else {            $exceptionHandler("不能再点击啦,点爆啦,哥们!");        }    };    $scope.handleClick = function () {        var localVars = { message: "第一次点击" };        $rootElement.injector().invoke(logClick, null, localVars);    };});

在这个示例中,$rootElement.injector().invoke(logClick, null, localVars) 会动态调用 logClick 函数,并将 localVars 作为参数注入到函数中。


$inject 对比 $injector

在 Angular 中,$inject$injector 是两个常用的依赖注入工具。$inject 更适合在控制器或其他注入位置直接注入服务,而 $injector 则用于程序matic获取服务实例。

以下是一个使用 $inject 的示例:

app.controller('indexCtrl', indexCtrl);indexCtrl.$inject = ['$scope', 'customService'];function indexCtrl($scope, customService) {    // 使用 customService...}

虽然 $inject$injector 看起来很相似,但它们在实现上有细微差别。通常情况下,$inject 会在注入过程中直接获取服务,而 $injector 则用于程序matic操作。


总结

通过本文的学习,我们掌握了 AngularJS 中依赖注入的核心机制,包括装饰器和 $injector 的使用方法。装饰器允许我们在服务、过滤器或指令被注册之前对其进行修改,而 $injector 则提供了程序matic获取和管理依赖项的能力。

在实际开发中,装饰器通常用于定制默认服务(如日志服务),而 $injector 则用于动态注入和管理组件。通过合理使用这些工具,我们可以构建出更灵活、可测试的 Angular 应用。

如果你对 Angular 的依赖注入机制还有其他疑问,欢迎在评论区留言!

转载地址:http://jmlzz.baihongyu.com/

你可能感兴趣的文章
npm安装crypto-js 如何安装crypto-js, python爬虫安装加解密插件 找不到模块crypto-js python报错解决丢失crypto-js模块
查看>>
npm安装教程
查看>>
npm报错Cannot find module ‘webpack‘ Require stack
查看>>
npm报错Failed at the node-sass@4.14.1 postinstall script
查看>>
npm报错fatal: Could not read from remote repository
查看>>
npm报错File to import not found or unreadable: @/assets/styles/global.scss.
查看>>
npm报错unable to access ‘https://github.com/sohee-lee7/Squire.git/‘
查看>>
npm淘宝镜像过期npm ERR! request to https://registry.npm.taobao.org/vuex failed, reason: certificate has ex
查看>>
npm版本过高问题
查看>>
npm的“--force“和“--legacy-peer-deps“参数
查看>>
npm的安装和更新---npm工作笔记002
查看>>
npm的常用配置项---npm工作笔记004
查看>>
npm的问题:config global `--global`, `--local` are deprecated. Use `--location=global` instead 的解决办法
查看>>
npm编译报错You may need an additional loader to handle the result of these loaders
查看>>
npm设置淘宝镜像、升级等
查看>>
npm设置源地址,npm官方地址
查看>>
npm设置镜像如淘宝:http://npm.taobao.org/
查看>>
npm配置安装最新淘宝镜像,旧镜像会errror
查看>>
NPM酷库052:sax,按流解析XML
查看>>
npm错误 gyp错误 vs版本不对 msvs_version不兼容
查看>>