学习目录

本文主要给大家介绍的是关于Angular 4依赖注入之Injectable装饰器的相关内容,分享出来供大家参考学习,下面来看看详细的介绍:
本系列教程的开发环境及开发语言:
基础知识
装饰器是什么
装饰器的分类
TypeScript 类装饰器
类装饰器声明:
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void
类装饰器顾名思义,就是用来装饰类的。它接收一个参数:
target: TFunction - 被装饰的类
看完第一眼后,是不是感觉都不好了。没事,我们马上来个例子:
function Greeter(target: Function): void {
target.prototype.greet = function (): void {
console.log('Hello!');
}
}
@Greeter
class Greeting {
constructor() { // 内部实现 }
}
let myGreeting = new Greeting();
myGreeting.greet(); // console output: 'Hello!';
上面的例子中,我们定义了 Greeter 类装饰器,同时我们使用了 @Greeter 语法,来使用装饰器。
Injectable 类装饰器使用
import { Injectable } from '@angular/core';
@Injectable()
class HeroService {}
Injectable 装饰器
在介绍 Injectable 装饰器前,我们先来回顾一下 HeroComponent 组件:
@Component({
selector: 'app-hero',
template: `
<ul>
<li *ngFor="let hero of heros">
ID: {{hero.id}} - Name: {{hero.name}}
</li>
</ul>
`
})
export class HeroComponent implements OnInit {
heros: Array<{ id: number; name: string }>;
constructor(private heroService: HeroService,
private loggerService: LoggerService) { }
ngOnInit() {
this.loggerService.log('Fetching heros...');
this.heros = this.heroService.getHeros();
}
}
在 HeroComponent 组件的 ngOnInit 生命周期钩子中,我们在获取英雄信息前输出相应的调试信息。其实为了避免在每个应用的组件中都添加 log 语句,我们可以把 log 语句放在 getHeros() 方法内。
更新前 HeroService 服务
export class HeroService {
heros: Array<{ id: number; name: string }> = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];
getHeros() {
return this.heros;
}
}
更新后 HeroService 服务
import { LoggerService } from './logger.service';
export class HeroService {
constructor(private loggerService: LoggerService) { }
heros: Array<{ id: number; name: string }> = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' }
];
getHeros() {
this.loggerService.log('Fetching heros...');
return this.heros;
}
}
当以上代码运行后会抛出以下异常信息:
Uncaught Error: Can't resolve all parameters for HeroService: (?).
上面异常信息说明无法解析 HeroService 的所有参数,而 HeroService 服务的构造函数如下:
export class HeroService {
constructor(private loggerService: LoggerService) { }
}
该构造函数的输入参数是 loggerService 且它的类型是 LoggerService 。在继续深入研究之前,我们来看一下 HeroService 最终生成的 ES5 代码:
var HeroService = (function() {
function HeroService(loggerService) {
this.loggerService = loggerService;
this.heros = [{...}, ...];
}
HeroService.prototype.getHeros = function() {
this.loggerService.log('Fetching heros...');
return this.heros;
};
return HeroService;
}());
我们发现生成的 ES5 代码中,HeroService 构造函数中是没有包含任何类型信息的,因此 Angular Injector (注入器) 就无法正常工作了。那么要怎么保存 HeroService 类构造函数中参数的类型信息呢?相信你已经想到了答案 — 当然是使用 Injectable 装饰器咯。接下来我们更新一下 HeroService:
import { Injectable } from '@angular/core';
import { LoggerService } from './logger.service';
@Injectable()
export class HeroService {
// ...
}
更新完上面的代码,成功保存后,在 http://localhost:4200/ 页面,你将看到熟悉的 "身影":
ID: 11 - Name: Mr. Nice ID: 12 - Name: Narco ID: 13 - Name: Bombasto ID: 14 - Name: Celeritas ID: 15 - Name: Magneta
现在我们再来看一下 HeroService 类生成的 ES5 代码:
var HeroService = (function() {
function HeroService(loggerService) {
this.loggerService = loggerService;
this.heros = [{...}, ...];
}
HeroService.prototype.getHeros = function() {
this.loggerService.log('Fetching heros...');
return this.heros;
};
return HeroService;
}());
HeroService = __decorate([__webpack_require__.i(
__WEBPACK_IMPORTED_MODULE_0__angular_core__["c"/* Injectable */
])(), __metadata("design:paramtypes", ...)], HeroService);
__decorate 函数
var __decorate = (this && this.__decorate) || function(decorators, target, key, desc) {...};
__metadata 函数
var __metadata = (this && this.__metadata) || function(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
return Reflect.metadata(k, v);
};
我们发现相比未使用 Injectable 装饰器,HeroService 服务生成的 ES5 代码多出了 HeroService = __decorate(...) 这些代码。简单起见,我稍微介绍一下,通过 Injectable 装饰器,在编译时会把 HeroService 服务构造函数中参数的类型信息,通过 Reflect API 保存在 window['__core-js_shared__'] 对象的内部属性中。当 Injector 创建 HeroService 对象时,会通过 Reflect API 去读取之前已保存的构造函数中参数的类型信息,进而正确的完成实例化操作。
我有话说
@Injectable() 是必须的么?
如果所创建的服务不依赖于其他对象,是可以不用使用 Injectable 类装饰器。但当该服务需要在构造函数中注入依赖对象,就需要使用 Injectable 装饰器。不过比较推荐的做法不管是否有依赖对象,在创建服务时都使用 Injectable 类装饰器。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者使用Angular 4能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# angular4
# 依赖注入
# angular
# injectable
# angularjs依赖注入
# 解决angularjs service中依赖注入$scope报错的问题
# 浅谈Angular6的服务和依赖注入
# 深入理解Angular中的依赖注入
# 深入理解Angular4中的依赖注入
# Angular 4依赖注入学习教程之InjectToken的使用(八)
# Angular基于Constructor Parameter的依赖注入方式详解
# 的是
# 好了
# 放在
# 都不
# 相关内容
# 我有
# 它是
# 我们可以
# 给大家
# 再来
# 看完
# 来看看
# 分别为
# 你已经
# 顾名思义
# 之二
# 这篇文章
# 看一下
# 你将
# 来个
相关文章:
如何选择高效可靠的多用户建站源码资源?
网站制作多少钱一个,建一个论坛网站大约需要多少钱?
可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?
如何有效防御Web建站篡改攻击?
C++中引用和指针有什么区别?(代码说明)
如何通过虚拟主机空间快速建站?
郑州企业网站制作公司,郑州招聘网站有哪些?
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?
Android滚轮选择时间控件使用详解
建站主机是什么?如何选择适合的建站主机?
如何在腾讯云服务器上快速搭建个人网站?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
如何用5美元大硬盘VPS安全高效搭建个人网站?
如何撰写建站申请书?关键要点有哪些?
小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化
制作营销网站公司,淘特是干什么用的?
Android使用GridView实现日历的简单功能
如何快速生成橙子建站落地页链接?
简单实现Android验证码
如何快速打造个性化非模板自助建站?
建站主机如何选?性能与价格怎样平衡?
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
香港网站服务器数量如何影响SEO优化效果?
建站之星如何通过成品分离优化网站效率?
如何在IIS服务器上快速部署高效网站?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
如何选择靠谱的建站公司加盟品牌?
再谈Python中的字符串与字符编码(推荐)
深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的?
网站制作说明怎么写,简述网页设计的流程并说明原因?
制作门户网站的参考文献在哪,小说网站怎么建立?
建站之星如何实现五合一智能建站与营销推广?
建设网站制作价格,怎样建立自己的公司网站?
建站主机是否属于云主机类型?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
如何在云指建站中生成FTP站点?
如何用PHP工具快速搭建高效网站?
图册素材网站设计制作软件,图册的导出方式有几种?
如何快速生成凡客建站的专业级图册?
免费ppt制作网站,有没有值得推荐的免费PPT网站?
深圳 网站制作,深圳招聘网站哪个比较好一点啊?
如何快速搭建支持数据库操作的智能建站平台?
小说建站VPS选用指南:性能对比、配置优化与建站方案解析
如何高效生成建站之星成品网站源码?
ppt制作免费网站有哪些,ppt模板免费下载网站?
建站之星如何配置系统实现高效建站?
Java解压缩zip - 解压缩多个文件或文件夹实例
娃派WAP自助建站:免费模板+移动优化,快速打造专业网站
武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?
*请认真填写需求信息,我们会在24小时内与您取得联系。