Angular 8 - 服务注入和工厂模式

2024-03-13

我已经简要阅读了几篇文章和官方 Angular 指南,但它们似乎无法帮助我解决我的任务。这就是我想要的和所做的。

假设我有带有产品列表页面的 Angular 应用程序。此外,这个应用程序将来还会有类别列表页面和一些N列表页面。正如您所看到的,它们非常相似,并且有一个共同的组件 - 数据表。

<app-data-table [type]="'product'"></app-data-table>

其实现如下:

import {Component, Input, OnInit} from '@angular/core';
import {DataFactoryService} from "../data-factory.service";

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

  @Input() type: string;

  private data: any[];

  constructor(private dataFactory: DataFactoryService) { }

  ngOnInit(): void {
    this.dataFactory.getServiceBy(this.type).selectAll();
  }

}

正如您可能已经猜到的那样,我的意思是使该组件服务类型不可知。这就是我创建并注入它的原因DataFactory:

import { Injectable } from '@angular/core';
import {ProductService} from "./product.service";
import {CategoryService} from "./category.service";
import {DataService} from "./data.service";

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

  private serviceTokenMapping = {
    "product": ProductService,
    "category": CategoryService
  };

  constructor() { }

  public getServiceBy(token: string): DataService {
    return new this.serviceTokenMapping[token];
  }
}

最后,我们有两个针对产品和类别的服务以及一些简单的基本抽象类:

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

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

  abstract selectAll(): any[];
}

import { Injectable } from '@angular/core';
import {DataService} from "./data.service";
import {Product} from "./product";

@Injectable({
  providedIn: 'root'
})
export class ProductService implements DataService {

  constructor() {}

  public selectAll(): Product[] {
    console.log(`ProductService...`);
    return [];
  }
}

import { Injectable } from '@angular/core';
import {DataService} from "./data.service";
import {Category} from "./category";

@Injectable({
  providedIn: 'root'
})
export class CategoryService implements DataService {

  constructor() {}

  public selectAll(): Category[] {
    console.log(`CategoryService...`);
    return [];
  }
}

有趣的是,这个实现完全按照预期工作。因此,我将表格类型作为产品相关页面的产品传递,类别类型用于类别等。

问题是,从 Angular 风格(提供者、DI 等)的角度来看,我是否做了一些不正确的事情,我们是否有任何方法来实现这样的要求,使其更加 Angular 风格?


我认为你实际上实例化了ProductService and CategoryService每次触发时this.dataFactory.getServiceBy(this.type)而实际上并没有在 Angular 中使用依赖注入。

您可以使用providers的财产@NgModule指定每个依赖项的标记并使用以下命令获取依赖项@Inject or injector.get.

export interface DataService {
  selectAll(): any[];
}

@Injectable({
  providedIn: 'root'
})
export class ProductService implements DataService {
  public static TOKEN = new InjectionToken<DataService>('ProductService_TOKEN');
  constructor() {}

  public selectAll(): Product[] {
    console.log(`ProductService...`);
    return [];
  }
}

@Injectable({
  providedIn: 'root'
})
export class CategoryService implements DataService {
  public static TOKEN = new InjectionToken<DataService>('CategoryService_TOKEN');
  constructor() {}

  public selectAll(): Category[] {
    console.log(`CategoryService...`);
    return [];
  }
}

@NgModule({
    providers: [
     {
        provide: ProductService.TOKEN,
        useExisting: forwardRef(() => ProductService),
        multi: false
     },
     {
        provide: CategoryService.TOKEN,
        useExisting: forwardRef(() => CategoryService),
        multi: false
     }
   ]
})
export class YourModule {}

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

  @Input() type: string;

  private data: any[];

  constructor(
     @Inject(ProductService.TOKEN) private dataService: DataService,
     private injector: Injector
   ) { }

  ngOnInit(): void {
    this.dataService.selectAll();
    this.injector.get<DataService>(CategoryService.TOKEN).selectAll();
  }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular 8 - 服务注入和工厂模式 的相关文章

随机推荐

  • 在尝试发送短信之前检查 Android 中的网络覆盖范围

    我想为 Android 智能手机创建一个应用程序来检查手机是否处于飞行模式 如果是 应用程序会使手机退出飞行模式 并检查是否有任何网络连接可以发送短信 当我说网络连接时 我指的是发送短信的手机网络覆盖范围 我不想检查互联网连接 如果有网络连
  • WPF DataGrid 网格线在另存为 PDF 时不可见

    我正在使用 DataGrid 来表示 WPF 应用程序中的一些数据 在我使用 PDFSharp 将具有 DataGrid 的特定 WPF 窗口保存到 PDF 的功能中 我遇到一个问题 即当以较小的查看百分比查看保存的 PDF 时 DataG
  • 我的 Rails 和 Cocoa 应用程序之间的 SHA1 哈希值不匹配

    我有一个 Cocoa 应用程序将一些数据以及该数据的 SHA1 哈希值发送到 Rails 应用程序 该应用程序验证数据和哈希值是否匹配 但它们不匹配 可以肯定的是 我已经记录了在 Rails 和 Cocoa 端散列到控制台的数据的十六进制版
  • 使用回溯的数独求解器

    我最近一直在研究回溯数独求解算法 目前我想问一下我应该如何将我的solve 方法从void更改为boolean 我正在使用一个非常简单的回溯算法 它目前工作正常 但我宁愿有一个布尔值而不是一个空值 因为有一个打印堆栈不是很好 Thanks
  • 如何截断C char*?

    就如此容易 顺便说一句 我正在使用 C 我已经阅读了 cplusplus com 的 cstdlib 库函数 但我找不到一个简单的函数 我知道字符的长度 我只需要erase最后三个字符 我可以使用 C 字符串 但这是用于处理文件 它使用 c
  • 计算一个字节中零和一的数量

    我之前发布了一个程序来查找一个字节中 1 的总数 现在我正在尝试查找一个字节中 0 的数量 以下是我的代码 MOV AL 1 MOV CX 08H MOV BX 0000H MOV DX 0000H Zero SHR AL 01H JZ e
  • 在 Android 中唤醒/睡眠时启动 Activity

    我想制作一个计时器 当 Android 设备被唤醒时开始计时 当 Android 设备设置为睡眠时停止计时 我什么也没找到 如何触发活动 通过唤醒 睡眠 我希望你能帮助我解决我的问题 我使用了像 timonvlad 所说的 Broadcas
  • C# 中的分段下载?

    请原谅我对这个问题的无知 我想用 C 编写一个应用程序 可以以相同的方式从服务器下载文件打倒他们 http www downthemall net 做 DownThemAll 似乎打开了四个到 HTTP 服务器的连接来下载同一文件 我只是想
  • 从 std::tuple 函数 QtConcurrentRun 获取(多)返回值

    您好 我有一个用于在 Qt 中生成某个文件的 MD5 的类 我使用元组从中返回多个值 我想在其他线程上运行它 因为生成所有文件 MD5 可能需要一些时间并且它的冻结 gui我决定使用Qt并发运行在其他线程上运行它 但到目前为止我对如何获取所
  • 捕获代号一中的未知主机异常

    我正在使用构建一个应用程序代号一 http www codenameone com 问题是 我需要使用该应用程序访问 URL 该 URL 返回了我在屏幕上显示的一些结果 所以我用这些行来做到这一点 ConnectionRequest c n
  • Spark 执行器无法访问 kubernetes 集群内的 ignite 节点

    我正在将我的 Spark 作业与现有的 ignite 集群连接起来 我使用服务帐户名spark为了它 我的驱动程序能够访问 ignite pod 但我的执行程序无法访问它 这就是执行程序日志的样子 Caused by java io IOE
  • mongodb count 与 find with count [重复]

    这个问题在这里已经有答案了 我正在对 mongo 版本 2 4 和 3 2 集合中的文档进行计数 馆藏非常大 有3821085篇文档 我需要统计所有文件并附上参考资料 id 我尝试了两种不同的查询 db SampleCollection f
  • 安装 .apk 时,如何将 .apk 中的某些文件解压到 /data/data/ 文件夹?

    我的 Android 应用程序需要另一个 NATIVE 应用程序可执行文件在 Android 应用程序之前运行 以便它们可以通过套接字进行通信 Android 应用程序有一个 JNI 层来处理客户端通信 现在我需要将本机可执行文件与 apk
  • Haskell 的“尾部”函数的时间复杂度是多少?

    当我在阅读 Haskell 教程时 我心里想 Haskell 的时间复杂度是多少tail功能有 以及为什么 我在任何文档中都找不到答案 我猜想对于一个大小为 n 的列表 tail函数将是O n 即将尾部复制到一个新列表并返回该列表 但话又说
  • AndEngine GLES2 中未找到 SimpleLevelLoader 类

    我是 AndEngine 的新手 工作时从AndEngine 教程 http www matim dev com full game tutorial part 11 html 未找到以下类 我尝试从 AndEngine 导入所有库 但仍然
  • 将 DataTable 转换为 JSON,每行包含键

    我认为以下将是一项非常常见的任务 并假设会有一个简单的解决方案 但我找不到 如果我有以下结构的数据表 ID Name Active ID1 John TRUE ID2 Bill FALSE 我想将其序列化为 JSON 对象 其中 ID 列是
  • 如何将浮点数数组转换为 byte[] 并返回?

    我有一个浮点数组需要转换为字节数组并返回浮点 任何人都可以帮助我正确地执行此操作吗 我正在使用 bitConverter 类 发现自己在尝试附加结果时陷入困境 我这样做的原因是为了可以将运行时值保存到 IO 流中 如果重要的话 目标存储是
  • jQuery noConflict() 问题

    因此 我正在一个每次加载页面时都会注入 jQuery 1 2 6 的平台上进行开发 我开发的页面使用 jQuery 1 4 2 因此当我的页面加载时 我的页面上有 2 个 jQuery 实例 为了避免任何冲突 我在页面外部的 JS 文件中包
  • 当 WHERE 子句中只有单个列时,SQL Server 是否会使用复合索引?

    假设我有一张桌子 CREATE TABLE Users Id INT IDENTITY 1 1 FirstName VARCHAR 40 LastName VARCHAR 40 查询通常是开启的名 or LastName 而且还关于名 an
  • Angular 8 - 服务注入和工厂模式

    我已经简要阅读了几篇文章和官方 Angular 指南 但它们似乎无法帮助我解决我的任务 这就是我想要的和所做的 假设我有带有产品列表页面的 Angular 应用程序 此外 这个应用程序将来还会有类别列表页面和一些N列表页面 正如您所看到的