Angular2学习笔记之依赖注入

前端之家收集整理的这篇文章主要介绍了Angular2学习笔记之依赖注入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

简介

依赖注入是重要的程序设计模式。 Angular 有自己的依赖注入框架,离开了它,几乎没法构建 Angular 应用。 
它使用得非常广泛,以至于几乎每个人都会把它简称为 DI。

注入器与提供器

注入器

//注入器
Constructor(private productService: ProductService ){ }

说明:

一般是在组件或者是服务中写入端代码,如果一个组件或者服务中的 constructor 注入为空。
就代表着这个组件或者服务没有注入任何的服务。

提供器

//提供器写法一
Providers:[ProductService]

//提供器写法二
Providers:[{provide: ProductService,userClass:ProductService}]

//提供器写法三
Providers:[{ provide: ProductService,userClass:AnotherProductService }]

//提供器写法四
Providers:[{ provide: ProductService,userFactory: () => { /*新建服务的方法*/ } }]

说明:

写法一:使用这种方法是默认的写法(也是最精简的写法),直接提供一个 ProuctService。
写法二:使用这种方法和默认的写法是一个意思。 
        provide: ProductService就是提供的是 ProductService服务。
        userClass:ProductService 就是我们new 这个服务对象的时候,new的是 ProductService。
写法三:使用这种方式,就是提供器提供的是 ProductService,但是 new 服务对象的时候, 
        new 的是 AnotherProductService。
写法四:使用工厂模式创建提供器

寻找依赖注入的逻辑

代码中找注入的方法:
1.在具体的组件或者服务中的 constructor 方法中找注入的服务
2.根据 1 中注入的服务找 提供器
3.跟据2 中的提供器找到对应的注入服务类

例:
注入器为 :Constructor(private productService: ProductService ){ }
就去找对应的 providers(提供器)
如果提供器为:Providers:[ProductService] 那么注入的就是 ProductService
如果提供器为:Providers:[{ provide: ProductService,userClass:AnotherProductService }] 
             那么注入的就是 AnotherProductService

依赖注入的层级结构

一方面,NgModule 中的提供商是被注册到根注入器。这意味着在 NgModule 中注册的提供商可以被整个应用访问。
另一方面,在应用组件中注册的提供商只在该组件及其子组件中可用。

关于 @Injectable()

@Injectable() 标识一个类可以被注入器实例化。 通常,在试图实例化没有被标识为@Injectable()的类时,注入器会报错。

官方建议:
建议:为每个服务类都添加 @INJECTABLE()
建议:为每个服务类都添加@Injectable(),包括那些没有依赖严格来说并不需要它的。因为:
    面向未来: 没有必要记得在后来添加依赖的时候添加 @Injectable()。
    一致性:所有的服务都遵循同样的规则,不需要考虑为什么某个地方少了一个。

"注意":
总是使用@Injectable()的形式,不能只用@Injectable。 如果忘了括号,应用就会神不知鬼不觉的报错!

最简单的例子

根模块中注入

目的:在新建的工程中将数据从Service中注入到component中,并且在界面上面展示出来
1.新建一个工程: ng new di
2.新建 product1 组件: ng g c product1
3.新建 product 服务(在shared 路径下面新建 product 服务): ng g service shared/product   或者   ng g s shared/product

修改代码 produc.service.ts:

/*
 增加 class Product, 以及返回 Product对象供外部调用方法 getProduct()
    getProduct方法需要返回一个 Product 。如果需要让外部访问到当前的 Service ,就需要加上一个注解  @Injectable()
*/
import { Injectable } from '@angular/core';

@Injectable()
export class ProductService {

  constructor() { }

  getProduct(): Product {
    return new Product(1,"IPhone X","最牛逼的全面屏手机",8388);
  }

}

export class Product{

  constructor(
    public id: number,public name: string,public desc: string,public price: number
  ){}
}

修改 product1.component.ts

/*
在当前的 Product 类中增加 变量 product 以及 注入 ProductService,在初始化的钩子中 调用 ProductService 的 getProduct 方法,返回一个 Product
*/
import { Component,OnInit } from '@angular/core';
import {Product,ProductService} from "../shared/product.service";

@Component({
  selector: 'app-product1',templateUrl: './product1.component.html',styleUrls: ['./product1.component.css']
})
export class Product1Component implements OnInit {

  product: Product;

  constructor(private productService: ProductService) { }

  ngOnInit() {
    this.product = this.productService.getProduct();
  }

}

修改 product1.component.html

<!-- 修改界面,用于界面展示 -->
<div>
  <div>商品编码:{{product.id}}</div>
  <div>商品名称:{{product.name}}</div>
  <div>商品描述:{{product.desc}}</div>
  <div>商品价格:{{product.price}}</div>
</div>

修改 app.conponent.html

<!-- 将 product.html 加入到 当前界面 -->
<h1>
  依赖注入的例子
</h1>


<div>
  <app-product1></app-product1>
</div>

修改 app.modules.ts

/*添加 Product.service.ts 到 providers 中,在这个地方注入是叫做 “从根组件中注入”,然后所有的都可以访问到。*/
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { Product1Component } from './product1/product1.component';
import {ProductService} from "app/shared/product.service";

@NgModule({
  declarations: [
    AppComponent,Product1Component
  ],imports: [
    BrowserModule,FormsModule,HttpModule
  ],providers: [ProductService],bootstrap: [AppComponent]
})
export class AppModule { }

图示:

猜你在找的Angularjs相关文章