一直以来对 Angular Providers
这部份都还是有存在着半知半解的状态,就趁着这次机会一次搞懂它吧!
Providers 提供了四种注入方式
将 service
的服务注入进来
product.ts
export class Product {
constructor(productID: number, name: string, price: number) {
this.productID = productID;
this.name = name;
this.price = price;
}
productID: number;
name: string;
price: number;
}
product.service
import { Injectable } from "@angular/core";
import { Product } from "./product";
@Injectable()
export class ProductService {
constructor() {}
public getProducts() {
let products: Product[];
products = [new Product(1, "Memory Card", 100)];
return products;
}
}
component.ts
@Component({
...略
providers: [ProductService],
})
export class AppComponent implements OnInit {
constructor(
private productService: ProductService,
) {
cosnole.log(
this.productService.getProducts()
// {productID: 1, name: 'Memory Card', price: 100}
)
}
}
直接在 providers 里的 useValue
设定想提供的值
const APP_CONFIG = Object.freeze({
serviceURL: 'mtwmt.github.io',
IsDevleomentMode: true,
});
@Component({
...略
providers: [
{ provide: 'USE_FAKE', useValue: true },
{ provide: 'APP_CONFIG', useValue: APP_CONFIG },
{
provide: 'FUNC',
useValue: () => {
return 'hello world';
},
},
{
provide: TestService,
useClass: TestService,
},
],
})
export class AppComponent implements OnInit {
constructor(
@Inject('USE_FAKE') public useFake: string,
@Inject('APP_CONFIG') public appConfig: any,
@Inject('FUNC') public func: any
) {
cosnole.log(
useFake, // true
appConfig,
// {
// serviceURL: 'mtwmt.github.io',
// IsDevleomentMode: true,
// }
func() // hello world
)
}
}
有时後会需要拿 useValue
的值 注到其他服务里做判断,这时後就可以使用 useFactory
,来处理一些逻辑上的事情
续上例:
这里多做了一个 MoreProductService
more-product.service
import { Injectable } from "@angular/core";
import { Product } from "./product";
@Injectable()
export class MoreProductService {
constructor() {}
public getProducts() {
let products: Product[];
products = [
new Product(1, "Memory Card", 500),
new Product(2, "Pen Drive", 750),
new Product(3, "Power Bank", 100),
new Product(4, "Laptop", 10000),
new Product(5, "Desktop", 100),
];
return products;
}
}
component.ts
import { Component, Inject, VERSION } from "@angular/core";
import { MoreProductService } from "./more-product.service";
import { ProductService } from "./product.service";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
providers: [
MoreProductService,
{
provide: "GET_MORE",
useValue: false,
},
{
provide: ProductService,
// 取得 GET_MORE 的 value,判断要产生的实体
useFactory: (isMore) => {
return isMore ? new MoreProductService() : new ProductService();
},
// 注入相依的 service
deps: ["GET_MORE", MoreProductService],
},
],
})
export class AppComponent {
products = [];
constructor(
@Inject("GET_MORE") public getMore: string,
private productService: ProductService
) {
this.products = this.productService.getProducts();
}
}
当想有新的 provide
想取代旧的 provide
时,可以使用 useExisting
来做取代,而不用再将源有的重新注入
实作如下:https://stackblitz.com/edit/angular-ivy-zhtp2w
参考文章:
This Won’t Hurt a Bit — Dependency Injection Tokens in Angular
Angular Providers: useClass, useValue, useFactory & useExisting
<<: [ Day 25 ] - 阵列的资料处理 - find
前中後运算式转置 中置运算式是人脑的计算中最直观且最习惯理解的表示式,会将运算子(EX:加号)放在两...
当你 google「Instagram 图片 下载」时 会发现不是要你用打开某网站然後操作操作操作!...
Navigation 的用处? 在一个 App 中一定会有很多页面, Navigation 提供简...
我可以吃,啊不对,是ISO27001可以吃,更不对XDDD"是赚来的钱钱可以买好吃的~(冷...
通常上传档案时,严谨一点,可能会需要做「档案格式检查」。 白话一点说,就是使用者上传的档案有没有符合...