ng-book札记——依赖注入
依赖注入是一种使程序的一部分能够访问另一部分的系统,并且可以通过配置控制其行为。
“注入”可以理解为是“new”操作符的一种替代,不再需要使用编程语言所提供的"new"操作符,依赖注入系统管理对象的生成。
依赖注入的最大好处是组件不再需要知道如何建立依赖项。它们只需要知道如何与依赖项交互。
在Angular的依赖注入系统中,不用直接导入并创建类的实例,而是使用Angular注册依赖,然后描述如何注入依赖,最后注入依赖。
依赖注入组件
为了注册一个依赖项,需要使用依赖标记(token)与之绑定。比如,注册一个API的URL,可以使用字符串API_URL作为其标记;如果是注册一个类,可以用类本身作为标记。
Angular中的依赖注入系统分为三部分:
- 提供者(Provider)(也被作为一个绑定)映射一个标记到一系列的依赖项,其告知Angular如何创建一个对象并给予一个标记。
- 注入器(Injector)持有一系列绑定,并负责解析依赖项,且在创建对象的时候注入它们。
- 依赖项(Dependency)是所注入的对象。

依赖注入方式
手动方式
通过ReflectiveInjector的resolveAndCreate方法解析并创建对象,这种方式不常用。
import { Injectable } from '@angular/core';
@Injectable()
export class UserService {
user: any;
setUser(newUser) {
this.user = newUser;
}
getUser(): any {
return this.user;
}
}
import {
Component,
ReflectiveInjector
} from '@angular/core';
import { UserService } from '../services/user.service';
@Component({
selector: 'app-injector-demo',
templateUrl: './user-demo.component.html',
styleUrls: ['./user-demo.component.css']
})
export class UserDemoInjectorComponent {
userName: string;
userService: UserService;
constructor() {
// Create an _injector_ and ask for it to resolve and create a UserService
const injector: any = ReflectiveInjector.resolveAndCreate([UserService]);
// use the injector to **get the instance** of the UserService
this.userService = injector.get(UserService);
}
signIn(): void {
// when we sign in, set the user
// this mimics filling out a login form
this.userService.setUser({
name: 'Nate Murray'
});
// now **read** the user name from the service
this.userName = this.userService.getUser().name;
console.log('User name is: ', this.userName);
}
}
* 注意UserService类上的@Injectable()装饰器,这说明了这个类是可以作为注入对象的。
NgModule方式
使用NgModule注册将要用到的依赖项(在providers中),并用装饰器(一般是构造器)指定哪些是正在使用的。
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
// imported here
import { UserService } from '../services/user.service';
@NgModule({
imports: [
CommonModule
],
providers: [
UserService // <-- added right here
],
declarations: []
})
export class UserDemoModule { }
import { Component, OnInit } from '@angular/core';
import { UserService } from '../services/user.service';
@Component({
selector: 'app-user-demo',
templateUrl: './user-demo.component.html',
styleUrls: ['./user-demo.component.css']
})
export class UserDemoComponent {
userName: string;
// removed `userService` because of constructor shorthand below
// Angular will inject the singleton instance of `UserService` here.
// We set it as a property with `private`.
constructor(private userService: UserService) {
// empty because we don't have to do anything else!
}
// below is the same...
signIn(): void {
// when we sign in, set the user
// this mimics filling out a login form
this.userService.setUser({
name: 'Nate Murray'
});
// now **read** the user name from the service
this.userName = this.userService.getUser().name;
console.log('User name is: ', this.userName);
}
}
Providers
类标记
providers: [ UserService ]是以下方式的的简写:
providers: [
{ provide: UserService, useClass: UserService }
]
provide是标记,useClass是所依赖的对象。两者为映射关系。
值标记
providers: [
{ provide: 'API_URL', useValue: 'http://my.api.com/v1' }
]
使用时需要加上@Inject:
import { Inject } from '@angular/core';
export class AnalyticsDemoComponent {
constructor(@Inject('API_URL') apiUrl: string) {
// works! do something w/ apiUrl
}
}
工厂方式
绑定依赖项时还可以通过工厂方式实现更复杂的绑定逻辑,并且这种方式下可以传入必要参数以创建所需的对象。
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {
Metric,
AnalyticsImplementation
} from './analytics-demo.interface';
import { AnalyticsService } from '../services/analytics.service';
// added this ->
import {
HttpModule,
Http
} from '@angular/http';
@NgModule({
imports: [
CommonModule,
HttpModule, // <-- added
],
providers: [
// add our API_URL provider
{ provide: 'API_URL', useValue: 'http://devserver.com' },
{
provide: AnalyticsService,
// add our `deps` to specify the factory depencies
deps: [ Http, 'API_URL' ],
// notice we've added arguments here
// the order matches the deps order
useFactory(http: Http, apiUrl: string) {
// create an implementation that will log the event
const loggingImplementation: AnalyticsImplementation = {
recordEvent: (metric: Metric): void => {
console.log('The metric is:', metric);
console.log('Sending to: ', apiUrl);
// ... You'd send the metric using http here ...
}
};
// create our new `AnalyticsService` with the implementation
return new AnalyticsService(loggingImplementation);
}
},
],
declarations: [ ]
})
export class AnalyticsDemoModule { }
ng-book札记——依赖注入的更多相关文章
- ng 依赖注入
将依赖的对象注入到当前对象,直接去使用依赖的对象即可. 降低耦合度.提高开发速度.. 文件压缩:yui-compressor有两种方案:①CLI(command line interface)java ...
- ng依赖注入
依赖注入 1.注入器在组件的构造函数中写服务constructor(private httpreq:HttpService) { } 2.提供器 providers: [HttpService],
- angular路由 模块 依赖注入
1.模块 var helloModule=angular.module('helloAngular',[]); helloModule.controller('helloNgCrtl',['$scop ...
- AngularJS学习笔记之依赖注入
最近在看AngularJS权威指南,由于各种各样的原因(主要是因为我没有money,好讨厌的有木有......),于是我选择了网上下载电子版的(因为它不要钱,哈哈...),字体也蛮清晰的,总体效果还不 ...
- 4.了解AngularJS模块和依赖注入
1.模块和依赖注入概述 1.了解模块 AngularJS模块是一种容器,把代码隔离并组织成简洁,整齐,可复用的块. 模块本身不提供直接的功能:包含其他提供功能的对象的实例:控制器,过滤器,服务,动画 ...
- AngularJS——依赖注入
依赖注入 依赖注入(DI)是一个经典的设计模式, 主要是用来处理组件如何获得依赖的问题.关于DI,推荐阅读Martin Flower的文章(http://martinfowler.com/art ...
- AngularJS学习--- AngularJS中XHR(AJAX)和依赖注入(DI) step5
前言:本文接前一篇文章,主要介绍什么是XHR,AJAX,DI,angularjs中如何使用XHR和DI. 1.切换工具目录 git checkout -f step- #切换分支 npm start ...
- angular2 学习笔记 ( DI 依赖注入 )
refer : http://blog.thoughtram.io/angular/2016/09/15/angular-2-final-is-out.html ( search Dependency ...
- (五)Angularjs - 依赖注入
如何找到API? AngularJS提供了一些功能的封装,但是当你试图通过全局对象angular去 访问这些功能时,却发现与以往遇到的库大不相同. 比如,AngularJS暴露了一个全局对象:angu ...
随机推荐
- Centos6.9minimal安装图形化界面
有时我们会用到图形化界面来操作,下面介绍是在虚拟机上安装Centos6.9minimal版安装图形化界面(其他系统版本都类似吧,,,),如果是在物理机上安装进入的话要用的远程桌面工具VNC. VNC安 ...
- Docker学习(1)安装
1. Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱 ...
- 2018 php的flush和ob_flush不起作用 整理解决
2018 php的flush和ob_flush不起作用 整理解决成功解决. 要点 : 使用函数 str_repeat2处配置:检查php.ini.Nginx 中有下面两个设置使用方式:echo str ...
- Hive函数:rank()、dense_rank()
数据准备: G1,KING, G1,BING, G2,FING, G1,FORD, G2,SCOTT, G1,JONES, G2,BLAKE, G1,CLARK, G1,ALLEN, G1,CELL1 ...
- PhantomJS命令行选项
支持命令行选项有: --help或-h列出所有可能的命令行选项.立即停止,不会运行一个脚本作为参数传递. --version或-v打印的版本PhantomJS.立即停止,不会运行一个脚本作为参数传递. ...
- beautiful soup
beautiful soup是一个可以从html或者xml文件中提取数据的python库,它能够通过你喜欢的转换器实现惯用的文档导航.查找.修改文档的方式. beautiful soup 会帮你节省数 ...
- UI前端开发都是做什么的以及html、css、php、js等究竟是神马关系
第一个问题: 1.UI,是视觉方面的呈现.一个网页首先由UI完成整体设计,然后把每一个模块切图,例如组件.logo.版块等.常用工具:PS,AI,DW. 2.前端,是将UI的设计代码化,因为计算机无法 ...
- Java入门1
一.eclipse的简单使用 1.新建项目 在package explorer的空白处点击右键,新建一个项目(new->Java Project)或者点击菜单栏的File->JavaPro ...
- Resource 的 IsSealed 问题
WFP 的 Generic.xaml ,App.xaml 等中的资源会被调用 Freezable. 在后台对该资源进行修改等操作会被提示.资源为密封对象. 如果,确定需要在后台对资源进行修改. 则需要 ...
- drupal 8 建立我的相册
一.先建一个存图片的内容类型 1.创建内容类型 点击[结构]>[内容类型]>[+add content type] 点击[保存和管理字段] 2.添加字段 点击[+添加字段] 点击[保存并继 ...