angulrJS依赖注入(三)-$inject

2024-06-09 06:58
文章标签 依赖 注入 inject angulrjs

本文主要是介绍angulrJS依赖注入(三)-$inject,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Dependency Injection (DI,依赖注入)是一种软件设计模式,用于处理如何让程序获得其依赖(对象的)引用。

依赖注入简述 | DI in a nutshell

对象或者函数只有以下3种获取其依赖(的对象)引用的方式:

  1. 依赖可以被使用者自己创建,通过 new 操作符.
  2. 依赖可以通过全局变量(如 window)来查找并引用
  3. 依赖可以在需要的地方被传入

前两种创建或查找依赖的方式并不是最优的,因为他们对依赖进行了硬编码. 这就使得当依赖变得不可用时,要修改依赖相关的代码变得非常困难和繁琐。在测试中更是有问题,因为通常需要通过模拟依赖来进行隔离测试。
第三种选择可以说是最可行的方式,因为它从组件中消除了查找依赖位置的责任。只需要简单地将依赖传递给组件即可。

要管理依赖创建的责任,每个 Angular 应用程序都有一个 injector 。该injector是一个 service locator(定位器) ,负责创建并查找依赖。
下面是一个使用 injector服务的示例:

    / 在一个模块中提供连接信息  angular.module('myModule', []).  // 告诉 injector 如何去构建一个 'greeter'  // 注意, greeter 自身是依赖于 '$window' 的  factory('greeter', function($window) {  // 这是一个 factory function,   // 职责是为创建  'greet' 服务.  return {  greet: function(text) {  $window.alert(text);  }  };  });  // 新的 injector 从  module 创建.   // (这通常由 angular bootstrap 自动创建)  var injector = angular.injector(['myModule', 'ng']);  // 从 injector 获取所有依赖  var greeter = injector.get('greeter');  

要解决依赖关系硬编码的问题,也就意味着 injector 需要贯穿整个应用程序生命周期。传递 injector 打破了 得墨忒耳定律(Law of Demeter, 最少知识原则)。为了弥补这一点,在下面的例子中,我们通过依赖声明的方式将查找依赖的职责交给了 injector:

HTML代码:[html] view plain copy 在CODE上查看代码片派生到我的代码片
<!-- Given this HTML -->  
<div ng-controller="MyController">  <button ng-click="sayHello()">Hello</button>  
</div>  
Angular代码
[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
// 这是 controller 定义  
function MyController($scope, greeter) {  $scope.sayHello = function() {  greeter.greet('Hello World');  };  
}  // 由 'ng-controller' directive 在后台执行  
injector.instantiate(MyController);  

注意通过 ng-controller实例化此类,它可以 在 controller 不知道有 injector 的情况下满足MyController 所有的依赖。这是最好的结果。应用程序代码简单地要求所需的依赖项,无需和 injector 打交道。这个设置不违背 得墨忒耳定律。

依赖注解 | Dependency Annotation

injector 怎么知道需要注入何种 service 呢?
为了解决依赖关系,应用程序开发者需要提供 injector 需要的 annotation 信息。在 Angular 中,某些API函数通过使用 injector 来调用,请按照API文档。injector 需要知道注入哪些服务给函数。下面是通过 service name 信息对代码进行注解的三种等价方式。他们都是等价的,你可以在适当的地方互换使用.

推断依赖关系 | Inferring Dependencies

最简单的获取依赖的方式,就是让函数参数名和依赖的名字一致。

[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
function MyController($scope, greeter) {  ...  
}  

给定一个 function, injector 通过检查函数声明和提取参数名称可以推断出 service 的名称 。在上面的例子中, $scope 和 greeter 是需要注入 function 的两个 services。
虽然简单直接, 但这种方法在 JavaScript 压缩/混淆 时会失效,因为会重命名方法的参数名。这使得这种注解方式只适用于 pretotyping, 或者 demo 程序中。

$inject 注解 | $inject Annotation

为了可以在压缩代码后依然可以注入正确的 services, 函数需要通过 inject. inject 属性是一个数组,包含 需要注入的 service 名字.

[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
var MyController = function(renamed$scope, renamedGreeter) {  ...  
}  
MyController['$inject'] = ['$scope', 'greeter'];  

在这种情况下,$inject数组中的值的顺序必须和要注入的参数的顺序一致。使用上面的代码片段作为一个例子, ‘ scoperenamed scope”, 而“greeter” 将注入到 “renamedGreeter”。再次提醒注意 $inject 注解必须和 函数声明时的实际参数保持同步(顺序,个数…)。对于 controller 声明,这种注解方法是很有用的,因为它将注解信息赋给了 function。

内联注解 | Inline Annotation

有时候并不方便使用 $inject 注解,比如在注解 directives的时候。
比如下面的示例:

[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
someModule.factory('greeter', function($window) {  ...  
});

因为需要使用临时变量,导致了代码膨胀为:

[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
var greeterFactory = function(renamed$window) {  ...  
};  
greeterFactory.$inject = ['$window'];  
someModule.factory('greeter', greeterFactory);  

这也是提供第三种注解方式的原因.

[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
someModule.factory('greeter', ['$window', function(renamed$window) {  ...  
}]);

记住,所有的 annotation 风格都是等价的,在 Angular 中,只有支持注入的地方都可以使用.

什么地方应该使用DI | Where can I use DI?

DI在 Angular 中无处不在。它通常用于 controllers 和工厂方法。

控制器中使用DI | DI in controllers

Controllers 类负责应用程序的行为。声明 controllers 的推荐的方法是使用数组表示法:
[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {  ...  $scope.aMethod = function() {  ...  }  ...  
}]);

这避免了为 controllers 创建全局函数,并且在代码压缩时继续可用.

工厂方法 | Factory methods

工厂方法在 Angular 中负责创建大多数的对象。例子是 directives, services, 以及 filters。工厂方法被注册到模块, 声明工厂的推荐方法是:

[javascript] view plain copy 在CODE上查看代码片派生到我的代码片
angular.module('myModule', []).  config(['depProvider', function(depProvider){  ...  }]).  factory('serviceId', ['depService', function(depService) {  ...  }]).  directive('directiveName', ['depService', function(depService) {  ...  }]).  filter('filterName', ['depService', function(depService) {  ...  }]).  run(['depService', function(depService) {  ...  }]);  

这篇关于angulrJS依赖注入(三)-$inject的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1044479

相关文章

SQL 注入攻击(SQL Injection)原理、利用方式与防御策略深度解析

《SQL注入攻击(SQLInjection)原理、利用方式与防御策略深度解析》本文将从SQL注入的基本原理、攻击方式、常见利用手法,到企业级防御方案进行全面讲解,以帮助开发者和安全人员更系统地理解... 目录一、前言二、SQL 注入攻击的基本概念三、SQL 注入常见类型分析1. 基于错误回显的注入(Erro

python依赖管理工具UV的安装和使用教程

《python依赖管理工具UV的安装和使用教程》UV是一个用Rust编写的Python包安装和依赖管理工具,比传统工具(如pip)有着更快、更高效的体验,:本文主要介绍python依赖管理工具UV... 目录前言一、命令安装uv二、手动编译安装2.1在archlinux安装uv的依赖工具2.2从github

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

Spring-DI依赖注入全过程

《Spring-DI依赖注入全过程》SpringDI是核心特性,通过容器管理依赖注入,降低耦合度,实现方式包括组件扫描、构造器/设值/字段注入、自动装配及作用域配置,支持灵活的依赖管理与生命周期控制,... 目录1. 什么是Spring DI?2.Spring如何做的DI3.总结1. 什么是Spring D

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter