热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Angular2多级注入器详解及实例

这篇文章主要介绍了Angular2多级注入器详解的相关资料,并附简单实例代码,需要的朋友可以参考下

angular2 的依赖注入包含了太多的内容,其中的一个重点就是注入器,而注入器又非常难理解,今天我们不深入介绍注入器的内容,可以参考官方文档,我们今天来说注入器的层级。

也就是组件获取服务的容器会选择具体哪一个。

先简单介绍一个背景:有3个组件AppComponent 根组件、DetailList组件 ( 日志列表组件)、Detail组件( 日志组件)。

这三个组件会形成一个组件树,对应的我们也可以认为每个组件都会有一个独立的注入器(有时候不会出现,但是可以这么认为)。

加入一个日志服务LoggerService,如果按照我们普通的入门方式,在根模块providers 中提供LoggerService。那么在整个应用程序中,LoggerService只有一个实例,什么意思呢?就是说无论在哪个组件,获取到的都是首次创建的LoggerService,所有组件共用一个服务实例,这有时候会是一个有用的特性,比如我们使用的全局配置。

全局唯一不是我们这次要验证的重点,因为这个太普通,我们这次要说明的是我们如何在每个组件中都获取单独的LoggerService实例,即每个组件的实例都不同。这个就需要对ng2的依赖注入有所了解才可以。

我们逐步来说明如何实现?

为了便于看到这篇短文的同学有所了解,我加入一些基础代码。

1.app.module.ts 应用程序根模块。注意此处我们没有在Providers中注册loggerService。当然注册了通过后面的方法也可以达到我们的目的。

import { NgModule, Optional, SkipSelf, ReflectiveInjector} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

/* App Root */
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { Title } from '@angular/platform-browser';
import {MessagesModule, GrowlModule, ButtonModule}from 'primeng/primeng';
import {AppDetailComponent}from './app-detail.component';
import {AppDetailListComponent}from './app-detailList.component';
import {LoggerService}from './logger.service';
let allTitle:string="郭志奇";

@NgModule({
 imports: [
 BrowserModule,
 MessagesModule,
 GrowlModule, ButtonModule
 ],
 declarations: [AppComponent, AppDetailComponent, AppDetailListComponent],//声明当前模块需要的指定 组件信息
 exports: [],
 providers: [Title],
 bootstrap: [AppComponent]
})
export class AppModule {
 constructor( @Optional() @SkipSelf() parentModule: AppModule) {
 console.log(parentModule);
 if (parentModule) {
  throw new Error(
  'AppModule is already loaded. Import it in the AppModule only');
 }
 }
}

2.app.component.ts  应用程序根组件

import { Component, ViewEncapsulation, Host, ViewContainerRef, ReflectiveInjector } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Message } from 'primeng/primeng';
import {LoggerService}from './logger.service';
@Component({
 selector: 'my-app',
 moduleId: module.id,
 templateUrl: './app.component.html',
 providers: [
  { provide: LoggerService, useClass: LoggerService }
 ]
})
export class AppComponent {
 subtitle = '(Final)';
 private msgs: Message[];
 constructor(private title: Title, @Host() private logger: LoggerService) {
  this.title.setTitle("AppComponent");
 }

 show(): void {
  this.logger.Debug();
 }
}

请注意,我们在跟组件中providers中注册了LoggerService。

3.app.detailList.ts  日志列表中providers中也注册了LoggerService

import {Component, Host}from '@angular/core';
import {LoggerService}from './logger.service';

@Component({
 selector: 'my-detailList',
 templateUrl: './app-detailList.component.html',
 moduleId: module.id,
 providers: [
  { provide: LoggerService, useClass: LoggerService }
 ]
})

export class AppDetailListComponent {
 constructor( private logger: LoggerService) {

 }
 show(): void {
  this.logger.Debug();
 }

}

 4.app.detail.ts  日志组件providers没有注册LoggerService。

import {Component, Host}from '@angular/core';
import {LoggerService}from './logger.service';
@Component({
 selector: 'detail',
 moduleId: module.id,
 templateUrl: './app-detail.component.html',
 providers: [
  // { provide: LoggerService, useClass: LoggerService }
 ]
})

export class AppDetailComponent {
 constructor( private logger: LoggerService) {

 }
 show(): void {
  this.logger.Debug();
 }

}

 现在我们通过chrome来看一下 LoggerService的层级关系。

 

通过查看依赖关系图,我们可以看到AppComponent组件使用了单独的LoggerService,DetailList组件也使用单独的LoggerService 实例,而Detail组件使用的是父组件DetailList的LoggerService实例。

目前来看没有达到我们的要求,我们的要求是每个组件都有单独的LoggerService实例,那么我们假设Detail组件的providers是我们忘记输入的,很难测试出原因所在。那么我们加入一个@Host()来限制注入器的查找范围。

对于注入器的向上查找方式,请参考官方文档。

为了便于调试,我们加入@Host().

@Host 装饰器将把往上搜索的行为截止在 宿主组件

detail.ts 提示detail组件加入@Host()装饰器

import {Component, Host}from '@angular/core';
import {LoggerService}from './logger.service';
@Component({
 selector: 'detail',
 moduleId: module.id,
 templateUrl: './app-detail.component.html',
 providers: [
  // { provide: LoggerService, useClass: LoggerService }
 ]
})

export class AppDetailComponent {
 constructor( @Host() private logger: LoggerService) {

 }
 show(): void {
  this.logger.Debug();
 }

}

会提示找不到LoggerService的实例,@Host()的作用就是限制注入器查找到当前组件就停止,不会继续往上查找。所以会出现找不到Providers的错误。

加上providers 的结果就是我们想要的了。

 

完美的解决了多组件使用单独服务实例的问题。

 总结:

1.如果要使组件单独使用服务,那么首先要在providers 中单独注册该服务。很容易理解

2.为了更好的检测可能出现的问题,在组件服务上加入@Host()装饰器,可以尽量早的抛出错误信息

3.使用ng2的debug工具

4.要明确各组件之间的关系,因为不同的组件关系会导致服务的实例的不同

5.服务尽量是模块级,不是应用级。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


推荐阅读
  • 自己用过的一些比较有用的css3新属性【HTML】
    web前端|html教程自己用过的一些比较用的css3新属性web前端-html教程css3刚推出不久,虽然大多数的css3属性在很多流行的浏览器中不支持,但我个人觉得还是要尽量开 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 本文探讨了在Linux系统上使用Docker时,通过volume将主机上的HTML5文件挂载到容器内部指定目录时遇到的403错误,并提供了解决方案和详细的操作步骤。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
  • 本文探讨了在 ASP.NET MVC 5 中实现松耦合组件的方法。通过分离关注点,应用程序的各个组件可以更加独立且易于维护和测试。文中详细介绍了依赖项注入(DI)及其在实现松耦合中的作用。 ... [详细]
  • 网易严选Java开发面试:MySQL索引深度解析
    本文详细记录了网易严选Java开发岗位的面试经验,特别针对MySQL索引相关的技术问题进行了深入探讨。通过本文,读者可以了解面试官常问的索引问题及其背后的原理。 ... [详细]
  • 本文详细介绍了 Flink 和 YARN 的交互机制。YARN 是 Hadoop 生态系统中的资源管理组件,类似于 Spark on YARN 的配置方式。我们将基于官方文档,深入探讨如何在 YARN 上部署和运行 Flink 任务。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 本文汇集了一系列具有强烈设计感的网站模板,特别是来自知名平台WrapBootstrap的响应式网站模板。这些模板不仅美观,而且功能强大,适合各种类型的网站建设需求。 ... [详细]
author-avatar
cryy5bl-1940
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有