使用 AOT 的类型提供程序中的角度条件

     2023-02-23     282

关键词:

【中文标题】使用 AOT 的类型提供程序中的角度条件【英文标题】:Angular condition in type provider with AOT 【发布时间】:2018-08-01 04:49:16 【问题描述】:

我有一个使用 AOT 编译的 Angular 项目。我希望能够注册根据配置动态解析的ClassProvider。我使用的简化代码是这样的:

const isMock = Math.random() > 0.5;

@NgModule(
  // ...
  providers: [
     provide: MyServiceBase, useClass: (isMock) ? MyServiceMock : MyService ,
  ],
  bootstrap: [AppComponent]
)
export class AppModule  

问题是当我用 AOT 编译它时,我总是得到相同的服务。我希望在按 F5 时获得不同的服务(因为第一行的randomness)。在没有 AOT 的情况下编译时,它的行为符合我的预期。

这是 github 上的完整代码示例:https://github.com/vdolek/angular-test/tree/aot-conditioned-provider-problem。它与 ng serveng serve --aot 的行为不同。

我怎样才能做到这一点?我知道我可以使用FactoryProvider,但是我必须复制服务依赖项(FactoryProvider 上的工厂函数和 deps 属性的参数)。

【问题讨论】:

【参考方案1】:

要实现您需求的动态特性,您需要通过useFactory 属性使用factory providers,。

我已经分叉了您的存储库,并修改了您的 app.module.ts 如下,以便在 AOT 中工作。

修改app.module.ts如下

export let myServiceFactory = () => 

  const isMock = Math.random() > 0.5;

  return isMock ? new MyServiceMock() : new MyService();
; 

@NgModule(
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    provide: MyServiceBase, useFactory: myServiceFactory,
  ],
  bootstrap: [AppComponent]
)
export class AppModule 

如果您的服务依赖于其他服务(很可能会),您可以使用 deps 参数传递所需的依赖关系。

假设MyServiceBase 依赖于两个服务,MyService1MyService2...您的工厂函数将如下所示:

export let myServiceFactory = (service1:MyService1, service2:MyService2) => 

  const isMock = Math.random() > 0.5;

  return isMock ? new MyServiceMock(service1, service2) : new MyService(service1, service2);
; 

您的提供者声明如下所示

providers: [
    
       provide: MyServiceBase, 
       useFactory: myServiceFactory,
       deps: [MyService1, MyService2]
    ,
]

This guide 包含有关在 Angular 中实现依赖注入的各种方法的更多详细信息。

【讨论】:

感谢您的回答。正如我在问题中提到的,我熟悉 FactoryProviders。但我不喜欢我需要列出三次依赖项(在实际服务中、在工厂签名中和在deps 属性中)。我想避免这种代码重复——这就是问题的目的。 deps 属性甚至不会在构建时进行静态检查,因此当有人更改服务的依赖项时,他必须知道更改 deps 属性。 我明白,我不得不承认,我错过了最后一句话(我的脑海里自动想到了那个解决方案)。据我所知,没有其他方法可以满足您的要求。 Angular 5 在使用 AOT 时减少了对工厂函数等语法的限制。【参考方案2】:

我认为正如@jeanpaul-a 所说,除了使用工厂之外,您别无选择。但是管理依赖关系可能不是很干净。但是您可以使用Injector。我会选择类似的东西:

@NgModule(
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  providers: [
    Dep1Service,
    Dep2Service,
     provide: MyServiceBase, useFactory: createService, deps: [Injector] 
  ],
  bootstrap:    [ AppComponent ]
)
export class AppModule  

export function createService(injector: Injector) 
  const isMock = Math.random() > 0.5;
  if (mock) 
    return new MyService1(injector.get(Dep2Service));
   else 
    return new MyService2(injector.get(Dep1Service));
  

您还可以将 MyServiceBase 设置为接口并使用InjectionToken。 您将找到一个工作示例 here(但不是您的班级名称)。

【讨论】:

感谢您的回答。这不是我 100% 的愿望。但至少每次依赖项发生变化时都会出现构建错误,因此人们知道需要更新工厂。 是的,我知道,但是你不能在 useClass 中使用函数调用,并且当使用 AOT 编译时,你的表达式将是静态的。所以如果你想要一些动态,你需要一个工厂

在角度通用应用程序(nodejs)上集成newrelic

...9:11:44【问题描述】:我正在nodejs应用程序上集成newrelic,使用AngularUniversal制作。我正在使用webpack进行捆绑ma​​in.server.aot.ts中的第一行constnewr 查看详情

如何使用 F# 中的类型提供程序连接到 SQL Server Compact Edition 4.0?

】如何使用F#中的类型提供程序连接到SQLServerCompactEdition4.0?【英文标题】:HowtoconnecttoSQLServerCompactEdition4.0withatypeproviderinF#?【发布时间】:2012-04-1415:36:14【问题描述】:我正在尝试从F#连接到SQLServerCompactEdition数据库,并尝试使... 查看详情

Angular AOT 组件中的相对路径

...。用ngc编译后,我有很多错误。我发现修复它们的方法是使用相对路径。所以我在所有组件中都使用了\'moduleId:module.id,\'。但现在 查看详情

如何根据使用角度 7 中的键的条件检查来过滤 json 响应中的数组

】如何根据使用角度7中的键的条件检查来过滤json响应中的数组【英文标题】:Howtogetfilteredthearrayinjsonreponsebasedonconditioncheckwithkeysinangular7【发布时间】:2020-07-2621:57:57【问题描述】:当dataID与使用Angular7中的打字稿功能的同一json... 查看详情

如何使用 ng build --aot 部署 Angular 应用程序?

】如何使用ngbuild--aot部署Angular应用程序?【英文标题】:Hotodeployangularappwithngbuild--aot?【发布时间】:2020-10-0313:17:29【问题描述】:我在localhost中使用angular创建了一个网站,一切正常,在heroku中也可以正常工作,现在我想将页面... 查看详情

角度 5 中的 <slot> 功能

...gular5【发布时间】:2019-04-2900:20:06【问题描述】:我正在使用SPA(单页应用程序),我使用Vue框架来开发应用程序。前端:Vue后端:NodeJs在我的应用程序中,我还有其他用Angular4编写的子模块,我想用Angular编写Vue提供的功能。Her... 查看详情

使用 formcontrol 将数据绑定到角度材料表中的复选框。数据以真假值列表的形式提供

】使用formcontrol将数据绑定到角度材料表中的复选框。数据以真假值列表的形式提供【英文标题】:Binddatatocheckboxinangularmaterialtableusingformcontrol.Dataisavailableaslistoftrue,falsevalues【发布时间】:2021-04-1712:09:10【问题描述】:HTML<ng-co... 查看详情

无法使用内容类型发布:从角度到轨道的应用程序/json

】无法使用内容类型发布:从角度到轨道的应用程序/json【英文标题】:CannotPOSTwithcontent-type:application/jsonfromangulartorails【发布时间】:2017-10-2900:44:12【问题描述】:所以我尝试使用Content-Type:application/json从Angular向我的Rails后端发... 查看详情

如何 AOT(提前)编译 C++ 程序

...布一个完整示例来说明如何执行示例“Hello,world!”在C++中使用LLVM和clang。我查看了llvm.org网站,找不到任何关于如何使用llvm进行AOT编译的文档。基本上我有兴趣学习如何进 查看详情

使用全局错误处理程序处理 NGXS(角度)中的错误

】使用全局错误处理程序处理NGXS(角度)中的错误【英文标题】:HandlingerrorsinNGXS(angular)withglobalerrorhandler【发布时间】:2019-11-1406:56:42【问题描述】:我想以两种方式处理NGXS中的错误。第一种方法是在组件中处理storedispatch的错... 查看详情

离子框架中的生产构建

...mework【发布时间】:2018-03-0409:44:24【问题描述】:最近我使用ionic3完成了一个项目,任何人都可以帮助我--aot或--prod为我们提供生产构建。cordovarunandroid--aot或cordovarunandroid--prod【问题讨论】:【参考方案1】:您要查找的命令是:... 查看详情

从进程角度看docker容器

...容器中的进程只能看到隔离的系统资源。LinuxNamespace的6大类型类型功能说明MountNamespace提供磁盘挂载点和文件系统的隔离能力IPCNamespace提供进程间通信的隔离能力NetworkNamespace提供网络隔离能力UTSNamespace提供主机名隔离能力PIDNamesp... 查看详情

java:泛型类型使用总结(代码片段)

...的类型安全同可以向后兼容。为了帮助读者更好地理解和使用型,本文通过一些示例从基本原理,重要概念,关键技术,以及相似技术比较等多个角度对Java语言中的泛型技术进行了介绍,重点强调了泛型中的... 查看详情

使用 @ngtools/webpack 在 Angular 11 + Webpack 4 中实现 AOT

】使用@ngtools/webpack在Angular11+Webpack4中实现AOT【英文标题】:ImplementingAOTinangular11+Webpack4using@ngtools/webpack【发布时间】:2021-04-0215:51:20【问题描述】:我正在尝试在不支持cli的angular项目中实现AOT。我搜索了一下,发现@ngtools/webpack... 查看详情

角度js +类型脚本中的动态列表

...pescripts【发布时间】:2018-12-0812:56:26【问题描述】:我想使用angulerjs创建以下动态列表。根据我的要求,水果、蔬菜等列集可以根据数据集动态变化。我想从json文件加载数据。例如:["clusterID":"1","storeCode":"S2HK","storeName":"store1"," 查看详情

NgxMuiDatatables 无法使用 --aot 编译

】NgxMuiDatatables无法使用--aot编译【英文标题】:NgxMuiDatatablesCannotcompileusing--aot【发布时间】:2020-01-1019:37:11【问题描述】:嘿,我试图将此库集成到我的Angular项目中,但出现以下错误:/Users/.../src/app中的模块“AppModule”导入的... 查看详情

如何使用角度将单元格 colspan 基于条件值?

】如何使用角度将单元格colspan基于条件值?【英文标题】:HowcanIbaseacellscolspanonaconditionalvalueusingangular?【发布时间】:2016-07-1713:19:14【问题描述】:基于html页面上其他地方的值,我需要在表格中的一行显示比表格中其他任何地... 查看详情

在 ng build--aot 期间,类型“any []”上不存在属性“名称”

...入字段。根据下拉列表的选择,设置输入字段值。所以我使用了any(Array)类型的数组。在我的.ts文件中,我是这样写的Services:Arr 查看详情