Angular学习笔记-提供器入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41012753/article/details/85161633

注入器

每一个组件都有一个注入器实例,负责注入组件需要的对象。
注入器是angular提供的一个服务类。
注入器自动通过通过组件的构造函数,将注入器的对象注入进组件

constructor(private productService:ProductService){...}

Angular的注入器在看到这样一个构造函数声明的时候,他就会在整个Angular项目中需要这样一个叫ProductService的实例,找到后就会把实例注入到productService的对象里面去,然后我们直接用就可以了。

那么,怎么产生这样一个ProductService呢?我们就需要指定提供器。

提供器

我们需要通过组件或者模块的providers属性来声明ProductService

providers:[ProductService]
//等价于

//provide是token,useClass是要new的东西
providers:[{provide:ProductService,useClass:ProductService}]

//我new的东西就是AnotherProductService
providers:[{provide:ProductService,useClass:AnotherProductService}]

//我们还可以通过工厂写一些代码来实例化对象
providers:[{provide:ProductService,useFactory:()=>{...}}]

也就是说,注入器会通过查找与提供器provide 中token哪个是一样的,而通过token后的useClass来实例化一个具体的类.

DEMO

声明一个组件和服务

ng g component product1
ng g service shared/product

我们在声明一个server时会有这样的报错
在这里插入图片描述
这是因为我们还有没声明提供器,别急
product.service.ts

import { Injectable } from '@angular/core';

export class ProductService {

  constructor() { }

  //声明一个getProduct方法,返回一个Product对象
  getProduct(): Product {
    return new Product(0,"iPhone7",5899,"最新款苹果手机")
  }
}

//定义一个用来封装商品信息的类
export class Product {
  //通过构造函数来定义里面的字段
  constructor(
    public id: number,
    public title: string,
    public price: number,
    public desc:string
  ) {}
}

然后我们写一下服务的提供器,打开app.module.ts
在这里插入图片描述
最后我们改写组件的逻辑,将服务注入进组件

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: Product;

  //在构造函数里,通过依赖注入声明我需要一个token类型是ProductService
  constructor(
    private productService:ProductService
  ) { }

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

我们将数组绑到页面,这个时候页面会显示

在这里插入图片描述
在上面这个例子里我们将提供器声明到了模块中,提供器也可以声明到组件中
我们在声明一个组件和一个服务

ng g component product2
ng g service shared/anotherProduct

antherProduct

import { Injectable } from '@angular/core';
import { ProductService, Product } from './product.service';

@Injectable({})
  //实现ProductService,这意味着他会和ProductService有相同的方法
export class AnotherProductService implements ProductService {
  getProduct(): Product {
    return new Product(1, "iPhone8s", 12299, "最新款苹果手机")
    }
  constructor() { }
}

Product2.component.ts

import { Component, OnInit } from '@angular/core';
import { Product, ProductService } from '../shared/product.service';
import { AnotherProductService } from '../shared/another-product.service';

@Component({
  selector: 'app-product2',
  templateUrl: './product2.component.html',
  styleUrls: ['./product2.component.css'],
  providers: [{
    provide:ProductService,useClass:AnotherProductService
  }]
})
export class Product2Component implements OnInit {

  //在组件里面声明一个product属性来接收服务中获取到的数据
  product: Product;

  //在构造函数里,通过依赖注入声明我需要一个tooken类型是ProductService
  constructor(
    private productService: ProductService
  ) { }

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

这样运行会得到下面的结果
下半部分的数据是从anotherProduct这个servers里获取的
在这里插入图片描述

提供器的作用域

当我们把服务声明在模块中时,这个服务对所有组件是可见的
当我们把服务声明在组件中时,这个服务对当前组件及子组件是可见的
在token相同的情况下,声明在模块中的要比组件优先级高

Injectable()

只有用Injectable装饰器,才能够把别的服务注入到当前服务里

服务间互相注入

声明一个服务,用来弹出信息

ng g service shared/logger
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class LoggerService {

  constructor() { }
  log(message: string) {
    console.log(message);
  }
}

在app.module.ts声明掉

providers:[LoggerService]

修改product的service
在这里插入图片描述

源码地址:https://github.com/WillXusd/Angular_DI_Demo

猜你喜欢

转载自blog.csdn.net/weixin_41012753/article/details/85161633