In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
这篇文章主要为大家展示了"Angular 4依赖注入之Injectable装饰器的示例分析",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Angular 4依赖注入之Injectable装饰器的示例分析"这篇文章吧。
开发环境及开发语言:
Angular 4 +
Angular CLI
TypeScript
基础知识
装饰器是什么
它是一个表达式
该表达式被执行后,返回一个函数
函数的入参分别为 targe、name 和 descriptor
执行该函数后,可能返回 descriptor 对象,用于配置 target 对象
装饰器的分类
类装饰器 (Class decorators)
属性装饰器 (Property decorators)
方法装饰器 (Method decorators)
参数装饰器 (Parameter decorators)
TypeScript 类装饰器
类装饰器声明:
declare type ClassDecorator = (target: TFunction) => TFunction | void
类装饰器顾名思义,就是用来装饰类的。它接收一个参数:
target: TFunction - 被装饰的类
看完第一眼后,是不是感觉都不好了。没事,我们马上来个例子:
function Greeter(target: Function): void { target.prototype.greet = function (): void { console.log('Hello!'); }}@Greeterclass 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: ` ID: {{hero.id}} - Name: {{hero.name}} `})export class HeroComponent implements OnInit { heros: Array; 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: 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: 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. NiceID: 12 - Name: NarcoID: 13 - Name: BombastoID: 14 - Name: CeleritasID: 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依赖注入之Injectable装饰器的示例分析"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.