angular示例

什么是依赖注入? (What is Dependency Injection?)

动机 (Motivation)

Dependency Injection is often more simply referred to as DI. The paradigm exists throughout Angular. It keeps code flexible, testable, and mutable. Classes can inherit external logic without knowing how to create it. Any consumers of those classes also do not need to know anything.

依赖注入通常更简单地称为DI。 该范例存在于整个Angular中。 它使代码保持灵活,可测试和可变的。 类可以继承外部逻辑而不知道如何创建它。 这些类别的任何消费者也无需了解任何信息。

DI saves classes and consumers alike from having to know more than necessary. Yet the code is as modular as it was before thanks to the mechanisms supporting DI in Angular.

DI可以使类和消费者免于不必要的了解。 然而,由于支持Angular中的DI的机制,代码与以前一样模块化。

Services are a key benefactor of DI. They rely on the paradigm for injection into various consumers. Those consumers can then take advantage of that service provides and/or forward it elsewhere.

服务是DI的关键受益者。 他们依靠这种范式注入各种消费者。 那些消费者然后可以利用该服务提供和/或将其转发到其他地方。

Service are not alone. Directives, pipes, components, and so on: every schematic in Angular benefits from DI in some way or another.

服务并不孤单。 指令,管道,组件等:Angular中的每个原理图都以某种方式受益于DI。

喷油器 (Injectors)

Injectors are data structures that store instructions detailing where and how services form. They act as intermediaries within the Angular DI system.

注入程序是存储指令的数据结构,这些指令详细说明了服务的位置和形成方式。 它们充当Angular DI系统中的中介。

Module, directive, and component classes contain metadata specific to injectors. A new injector instance accompanies every one of these classes. In this way, the application tree mirrors its hierarchy of injectors.

模块,指令和组件类包含特定于注入器的元数据。 这些类别中的每一个都伴随着一个新的喷射器实例。 这样,应用程序树将镜像其注射器的层次结构。

The providers: [] metadata accepts services that then register with the class’ injector. This provider field adds the instructions necessary for an injector to function. A class (assuming it has dependencies) instantiates a service by taking on its class as its data type. The injector aligns this type a creates an instance of that service on the class’ behalf.

providers: []元数据接受服务,然后向类的注入器注册。 该提供者字段添加了注射器工作所需的指令。 一个类(假设它具有依赖性)通过将其类作为其数据类型来实例化服务。 注入器将对齐此类型,并代表类创建该服务的实例。

Of course, the class can only instantiate what the injector has instructions for. If the class’ own injector does not have the service registered, then it queries its parent. So on and so forth until either reaching an injector with the service or the application root.

当然,该类只能实例化注入器的指令。 如果类自己的注入器未注册服务,则它将查询其父级。 依此类推,直到到达具有服务或应用程序根目录的注入器为止。

Services can register at any injector within the application. Services go in the providers: [] metadata field of class modules, directives, or components. The class’ children can instantiate a service registered in the class’ injector. Child injectors fallback on parent injectors after all.

服务可以在应用程序内的任何注入器处注册。 服务位于providers: []类模块,指令或组件的providers: []元数据字段。 班级的孩子可以实例化在班级的注射器中注册的服务。 毕竟,子喷射器在父喷射器上回退。

依赖注入 (Dependency Injection)

Take a look at the skeletons for each class: service, module, directive, and component.

看一下每个类的框架:服务,模块,指令和组件。

// serviceimport { Injectable } from '@angular/core';@Injectable({providedIn: /* injector goes here */
})
export class TemplateService {constructor() { }
}
// moduleimport { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';@NgModule({imports: [CommonModule],declarations: [],providers: [ /* services go here */ ]
})
export class TemplateModule { }
// directiveimport { Directive } from '@angular/core';@Directive({selector: '[appTemplate]',providers: [ /* services go here */ ]
})
export class TemplateDirective {constructor() { }
}
//componentimport { Component } from '@angular/core';@Component({selector: 'app-template',templateUrl: './template.component.html',styleUrls: ['./template.component.css'],providers: [ /* services go here */ ]
})
export class TemplateComponent {// class logic ...
}

Each skeleton can register services to an injector. In fact, TemplateService is a service. As of Angular 6, services can now register with injectors using @Injectable metadata.

每个骨架都可以向喷射器注册服务。 实际上,TemplateService 一项服务。 从Angular 6开始,服务现在可以使用@Injectable元数据向注入器注册。

任何状况之下 (In Any Case)

Notice the providedIn: string (@Injectable) and providers: [] (@Directive, @Componet and @Module) metadata. They tell injectors where and how to create a service. Otherwise, injectors would not know how to instantiate.

注意providers: [] providedIn: string ( @Injectable )和providers: [] ( @Directive@Componet @Module@Module )元数据。 他们告诉注入者在哪里以及如何创建服务。 否则,注入器将不知道如何实例化。

What if a service has dependencies? Where would the results go? Providers answers those question so that injectors can instantiate properly.

如果服务具有依赖项怎么办? 结果会去哪里? 提供者回答这些问题,以便注入器可以正确实例化。

Injectors form the backbone of the DI framework. They store instructions to instantiate services so consumers do not have to. They receive service instances without needing to know anything about the source dependency!

注入器构成了DI框架的骨干。 它们存储指令以实例化服务,因此消费者不必这样做。 他们接收服务实例,而无需了解任何有关源依赖的知识!

I should also note that other schematics without injectors can still utilize dependency injection. They cannot register additional services but they can still instantiate from injectors.

我还要注意,其他没有注入器的原理图仍然可以使用依赖注入。 他们无法注册其他服务,但仍可以从注入器实例化。

服务 (Service)

The providedIn: string metadata of @Injectable specifies which injector to register with. Using this method, and depending on if the service gets used, the service may or may not register with the injector. Angular calls this tree-shaking.

@Injectable providedIn: string元数据指定@Injectable哪个注入器注册。 使用此方法,并取决于是否使用服务,该服务可能会或可能不会在注射器中注册。 Angular称此为摇树

By default the value is set to ‘root’. This translates to the root injector of the application. Basically, setting the field to ‘root’ makes the service available anywhere.

默认情况下,该值设置为'root' 。 这将转换为应用程序的根注入器。 基本上,将字段设置为'root'可使服务在任何地方可用。

快速说明 (Quick Note)

As previously mentioned, child injectors fallback on their parents. This fallback strategy ensures parents do not have to re-register for every injector. Refer to this article on Services and Injectors for an illustration of this concept.

如前所述,儿童喷油器退回给父母。 这种后备策略可确保父母不必为每个注射器都重新注册。 有关此概念的说明,请参阅有关服务和注射器的本文。

Registered services are singletons. Meaning, the instructions to instantiate the service exists on only one injector. This assumes it has not been explicitly registered elsewhere.

注册服务为单例 。 意思是,实例化服务的指令仅存在于一个注射器上。 这假定它尚未在其他地方显式注册。

模块,指令和组件 (Module, Directive, and Component)

Modules and components each have their own injector instance. This is evident given the providers: [] metadata field. This field takes an array of services and registers them with the injector of the module or component class. This approach happens in the @NgModule, @Directive, or @Component decorators.

每个模块和组件都有自己的注射器实例。 从providers: []来看这很明显providers: []元数据字段。 该字段采用服务数组,并向模块或组件类的注入器注册它们。 这种方法发生在@NgModule @Directive@Component @Directive@Component装饰器中。

This strategy omits tree-shaking, or the optional removal of unused services from injectors. Service instances live on their injectors for the life of the module or component.

该策略省去了摇树或从注入器中删除未使用服务的可选操作。 服务实例在模块或组件的整个生命周期内都驻留在其注入器上。

实例化引用 (Instantiating References)

References to the DOM can instantiate from any class. Keep in mind that references are still services. They differ from traditional services in representing the state of something else. These services include functions to interact with their reference.

可以从任何类实例化对DOM的引用。 请记住,引用仍然是服务。 它们与传统服务的不同之处在于代表了其他状态。 这些服务包括与参考进行交互的功能。

Directives are in constant need of DOM references. Directives perform mutations on their host elements through these references. See the following example. The directive’s injector instantiates a reference of the host element into the class’ constructor.

指令始终需要DOM引用。 指令通过这些引用在其宿主元素上执行突变。 请参见以下示例。 指令的注入器将宿主元素的引用实例化到类的构造函数中。

// directives/highlight.directive.tsimport { Directive, ElementRef, Renderer2, Input } from '@angular/core';@Directive({selector: '[appHighlight]'
})
export class HighlightDirective {constructor(private renderer: Renderer2,private host: ElementRef) { }@Input() set appHighlight (color: string) {this.renderer.setStyle(this.host.nativeElement, 'background-color', color);}
}
// app.component.html<p [appHighlight]="'yellow'">Highlighted Text!</p>

Renderer2 also gets instantiated. Which injector do these services come from? Well, each service’s source code comes from @angular/core. These services must then register with the application’s root injector.

Renderer2也被实例化。 这些服务来自哪个喷油嘴? 好吧,每个服务的源代码都来自@angular/core 。 然后,这些服务必须在应用程序的根注入器中注册。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HighlightDirective } from './directives/highlight.directive';@NgModule({declarations: [AppComponent,HighlightDirective],imports: [BrowserModule],providers: [],bootstrap: [AppComponent]
})
export class AppModule { }

An empty providers array!? Not to fear. Angular registers many services with the root injector automatically. This includes ElementRef and Renderer2. In this example, we are managing the host element through its interface stemming from the instantiation of ElementRef. Renderer2 lets us update the DOM through Angular’s view model.

空的提供程序数组! 不要害怕。 Angular自动向根注入器注册许多服务。 这包括ElementRefRenderer2 。 在此示例中,我们通过源自ElementRef实例化的接口来管理宿主元素。 Renderer2让我们通过Angular的视图模型更新DOM。

You can read more about views from this article. They are the preferred method for DOM/view updates in Angular applications.

您可以从本文中了解有关视图的更多信息。 它们是Angular应用程序中DOM /视图更新的首选方法。

It is important recognize the role that injectors play in the above example. By declaring variable types in the constructor, the class obtains valuable services. Each parameter’s data type maps to a set of instructions within the injector. If the injector has that type, it returns an instance of said type.

重要的是要认识到喷射器在以上示例中所扮演的角色。 通过在构造函数中声明变量类型,该类可以获得有价值的服务。 每个参数的数据类型都映射到注射器内的一组指令。 如果注入器具有该类型,则返回该类型的实例。

实例化服务 (Instantiating Services)

The Services and Injectors article explains this section to an extent. Though, this section rehashes the previous section or the most part. Services will often provide references to something else. They may just as well provide an interface extending a class’ capabilities.

服务和喷射器文章在一定程度上解释了此部分。 但是,本节将重整上一节或大部分内容。 服务通常会提供对其他内容的引用。 它们也可能提供扩展类功能的接口。

The next example will define a logging service that gets added to a component’s injector via its providers: [] metadata.

下一个示例将定义一个日志记录服务,该服务通过其providers: []添加到组件的注入器providers: []元数据。

// services/logger.service.tsimport { Injectable } from '@angular/core';@Injectable()
export class LoggerService {callStack: string[] = [];addLog(message: string): void {this.callStack = [message].concat(this.callStack);this.printHead();}clear(): void {this.printLog();this.callStack = [];console.log(“DELETED LOG”);}private printHead(): void {console.log(this.callStack[0] || null);}private printLog(): void {this.callStack.reverse().forEach((log) => console.log(message));}
}
// app.component.tsimport { Component } from '@angular/core';
import { LoggerService } from './services/logger.service';@Component({selector: 'app-root',templateUrl: './app.component.html',providers: [LoggerService]
})
export class AppComponent {constructor(private logger: LoggerService) { }logMessage(event: any, message: string): void {event.preventDefault();this.logger.addLog(`Message: ${message}`);}clearLog(): void {this.logger.clear();}
}
// app.component.html<h1>Log Example</h1>
<form (submit)="logMessage($event, userInput.value)"><input #userInput placeholder="Type a message..."><button type="submit">SUBMIT</button>
</form><h3>Delete Logged Messages</h3>
<button type="button" (click)="clearLog()">CLEAR</button>

Focus on the AppComponent constructor and metadata. The component injector receives instructions from the provider’s metadata field containing LoggerService. The injector then knows what to instantiate LoggerService from requested in the constructor.

专注于AppComponent构造函数和元数据。 组件注入器从包含LoggerService的提供程序的元数据字段接收指令。 然后,注入器知道从构造函数中请求实例化LoggerService的方式。

The constructor parameter loggerService has the type LoggerService which the injector recognizes. The injector follows through with the instantiation as mentioned.

构造函数参数loggerService具有注入器可识别的LoggerService类型。 注入程序执行上述实例化。

结论 (Conclusion)

Dependency injection (DI) is a paradigm. The way it works in Angular is through a hierarchy of injectors. A class receives its resources without having to create or know about them. Injectors receive instruction and instantiate a service depending on which one was requested.

依赖注入(DI)是一种范例。 它在Angular中的工作方式是通过注射器的层次结构。 类无需创建或了解资源就可以获取其资源。 注入器接收指令并根据所请求的服务实例化服务。

DI shows up a lot in Angular. The official Angular documentation explains why the paradigm is so prevalent. They also go on to describe the numerous use-cases for DI in Angular way beyond what was discussed in this article. Check it out by clicking below!

DI在Angular中显示很多。 Angular官方文档解释了为什么这种范式如此普遍。 除了本文讨论的内容外,他们还以Angular方式描述了DI的众多用例。 点击下面查看!

有关依赖项注入的更多信息: (More on dependency injection:)

  • Intro to Angular dependency injection

    Angular依赖注入简介

  • Quick intro to dependency injection

    快速介绍依赖注入

翻译自: https://www.freecodecamp.org/news/angular-dependency-injection/

angular示例

angular示例_Angular Dependency Injection用示例解释相关推荐

  1. php 依赖注入框架,依赖注入模式(Dependency Injection)

    依赖注入模式(Dependency Injection) 由 学院君 创建于5年前, 最后更新于 10个月前 版本号 #3 18333 views 16 likes 0 collects 1.模式定义 ...

  2. 依赖注入(Dependency Injection)框架是如何实现的?

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/fuzhongmin05/ article/details/109572151 当创建对象是一件庞大又复杂的大工程的时候,我们一 ...

  3. SAP Spartacus 中的依赖注入 Dependency Injection 介绍

    先了解 Angular 中的依赖注入 依赖项是指某个类执行其功能所需的服务或对象.依赖项注入(DI)是一种设计模式,在这种设计模式中,类会从外部源请求依赖项而不是让类自己来创建它们. Angular ...

  4. 再谈angularjs DI(Dependency Injection)

    在前面已经介绍了关于angularjs,以及扩展了一些jQuery ui的一些组件为angularjs的directive.在这里应进口007 在上篇留言我们来看看在angularjs中的DI特性. ...

  5. php service locator,Dependency Injection 和 Service Locator

    如果说学院派的 Java 程序员骨子里都浸淫着学究范儿的话,那么游击队出身的 PHP 程序员则从头到脚洋溢着乡土气息.通常他们不太在意理论,一切以实现为先,虽然这样的做法在项目早期能获得不错的收益,但 ...

  6. Spring IoC容器和Dependency Injection模式

    轻松学习Spring<一> IoC容器和Dependency Injection模式 最近公司需要,项目中要用到Spring和Ibatis.趁着过年好好学习学习.Ibatis就如同Hibe ...

  7. Dependency injection in ASP.NET Core

    原文 github地址 ASP.NET Core supports the dependency injection (DI) software design pattern, which is a ...

  8. IoC容器和Dependency Injection模式

    注:本文转自http://insights.thoughtworkers.org/injection/,请尊重译者的劳动成果,转载需注明出处. 2017年3月3日 by Martin Fowler L ...

  9. [.NET] Rough Dependency Injection

    动机 在设计系统架构的时候,在系统里加入Dependency Injection(DI),让系统可以在不改变程序代码的状况下,抽换类别来提高重用性.扩充性.在.NET里可以选择一些的Framework ...

最新文章

  1. 新建eclipse的java项目报错处理
  2. 遇到MapStruct后,再也不手写PO,DTO,VO对象之间的转换了
  3. 科技管理的第一个作业
  4. Java的List转Scala的数组
  5. [css] 说说你对GPU的理解,举例说明哪些元素能触发GPU硬件加速?
  6. UI自动化之读取浏览器配置
  7. 给软件工程师的学习参考
  8. .rpt文件内容读取java_python读取PDF指定表格内容批量文件重命名
  9. C++中利用输入输入流进行一行输入
  10. 网站pv 和服务器数量,聊一聊PV和并发、以及计算web服务器的数量的方法
  11. Java多线程并发编程实践总结
  12. Python汉字转拼音-拼音转汉字的效率测评
  13. 基于java实现学科竞赛管理系统「Springboot+mybatis+lyaui」
  14. c语言窗口炸弹代码,C语言实现宾果消消乐
  15. 基于android的轻餐饮点餐APP(ssm+uinapp+Mysql)
  16. 菜鸟入门_Python_机器学习(1)_线性可分的双月实验
  17. Xbox 360抢鲜测评
  18. 视频教程-《信息学竞赛-C语言》 DAY30-清华尹成老师-C/C++
  19. Java输出一个数组
  20. 灰关联分析与语音/音乐信号识别

热门文章

  1. 【今日CS 视觉论文速览】Tue, 15 Jan 2019
  2. 【今日CV 视觉论文速览】16 Nov 2018
  3. Java—Remove Deplicates from Sorted Array(顺序数组中去重位置)
  4. 区块链100讲:区块链的TPS性能
  5. EF连接ORACLE
  6. SQL Server 之 在与SQLServer建立连接时出现与网络相关的或特定于实例的错误
  7. 2012微软校园招聘笔试题
  8. 手动安装lzop压缩工具 - JerryMo06的专栏 - 博客频道 - CSDN.NET
  9. 我的家庭私有云计划-10
  10. 词法分析器生成工具flex