如何解决当我尝试在Angular 10中使用库中的服务时,“无法解析服务的所有参数:?”
在我的图书馆中,我使用以下代码提供服务:
import { Inject,Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DataInjectorModule } from '../../data-injector.module';
// @dynamic
@Injectable()
export class RemoteDataService<T> {
@Inject('env') private environment: any = {};
public type: new () => T;
constructor(
model: T,) {
this.http = DataInjectorModule.InjectorInstance.get(HttpClient);
}
// ...
}
data-injector.module
(现有原因仅是避免循环依赖):
import { NgModule,Injector } from '@angular/core';
// @dynamic
@NgModule({
declarations: [],imports: [],providers: [],exports: [],})
export class DataInjectorModule {
static InjectorInstance: Injector;
constructor(injector: Injector) {
DataInjectorModule.InjectorInstance = injector;
}
}
在我的图书馆的主模块文件中:
import { ModuleWithProviders } from '@angular/compiler/src/core';
import { NgModule,Injector } from '@angular/core';
import { DataInjectorModule } from './data-injector.module';
import { RemoteDataService } from './services/remote-data/remote-data.service';
// @dynamic
@NgModule({
declarations: [],imports: [
DataInjectorModule,],})
export class DataCoreModule {
static InjectorInstance: Injector;
constructor(injector: Injector) {
DataCoreModule.InjectorInstance = injector;
}
public static forRoot(environment: any): ModuleWithProviders {
return {
ngModule: DataCoreModule,providers: [
RemoteDataService,{ provide: 'env',useValue: environment }
]
};
}
}
最后在我应用程序的app.module.ts
中:
import { browserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { DataCoreModule } from 'data-core';
import { AppRoutingModule } from './app-routing.module';
import { environment } from 'src/environments/environment';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent,imports: [
browserModule,AppRoutingModule,DdataCoreModule.forRoot(environment),bootstrap: [AppComponent]
})
export class AppModule { }
构建进展顺利,但在浏览器中出现此错误:
Error: Can't resolve all parameters for RemoteDataService: (?).
at getUndecoratedInjectableFactory (core.js:11338)
at injectableDefOrInjectorDefFactory (core.js:11328)
at providerToFactory (core.js:11371)
at providerToRecord (core.js:11358)
at R3Injector.processprovider (core.js:11256)
at core.js:11230
at core.js:1146
at Array.forEach (<anonymous>)
at deepForEach (core.js:1146)
at R3Injector.processInjectorType (core.js:11230)
我在StackOverflow中检查了关于此主题的几个问题,例如this,但是几乎所有地方都只缺少@Injectable()
,但是在这种情况下,我使用了这种装饰器。
有什么主意我该如何解决这个问题?
解决方法
错误:无法解析RemoteDataService的所有参数:(?)
错误说明了一切。 Angular无法解析RemoteDataService中的所有构造函数参数。实例化此服务后,它将需要必需的参数。
您可以通过InjectionToken提供所需的依赖关系,有关详细信息,请参见this答案。
但是您的服务使用generics
,并且您没有提到如何在组件中使用此服务,因此建议您在组件中声明提供程序(或模块也可以使用)并使用{ {1}}可以在您的组件中注入该服务的不同版本,如下所示(签出this StackBlitz并查看控制台中来自服务构造函数的日志)-
@Inject()
此外,不确定是否可以在构造函数外部使用import { Component,Inject } from "@angular/core";
import { RemoteDataService } from "./custom/remote-data.service";
export class A {}
export class B {}
@Component({
selector: "my-app",templateUrl: "./app.component.html",styleUrls: ["./app.component.css"],providers: [
{ provide: "env",useValue: {} },{
provide: "ARemoteDataService",useFactory: () => new RemoteDataService<A>(new A())
},{
provide: "BRemoteDataService",useFactory: () => new RemoteDataService<B>(new B())
}
]
})
export class AppComponent {
constructor(
@Inject("ARemoteDataService")
private aRemoteDataService: RemoteDataService<A>,@Inject("BRemoteDataService")
private bRemoteDataService: RemoteDataService<B>
) {}
}
。但是,您始终可以使用注入器来获取其他依赖项(在您的情况下为@Inject()
)-
env
}
,我找到了解决方案(实际上是一种解决方法)。我认为这不是一种优雅的方法,但是很容易。
我创建了一个EnvService
类,该类可以从模块中获取environment
参数,并且没有构造函数属性的副作用:
import { Inject,Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',})
export class EnvService {
public environment: any = {};
constructor(@Inject('env') private env?: any) {
this.environment = env ?? {};
}
}
然后在库的主模块文件中设置EnvService
而不是RemoteDataService
:
import { ModuleWithProviders } from '@angular/compiler/src/core';
import { NgModule,Injector } from '@angular/core';
import { DataInjectorModule } from './data-injector.module';
import { EnvService } from './services/env/env.service';
// @dynamic
@NgModule({
declarations: [],imports: [
DataInjectorModule,],providers: [],exports: [],})
export class DataCoreModule {
static InjectorInstance: Injector;
constructor(injector: Injector) {
DataCoreModule.InjectorInstance = injector;
}
public static forRoot(environment: any): ModuleWithProviders {
return {
ngModule: DataCoreModule,providers: [
EnvService,{ provide: 'env',useValue: environment }
]
};
}
}
最后,在我的RemoteDataService
中,将@Inject
解决方案更改为InjectorInstance.get(EnvService)
解决方案:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DataInjectorModule } from '../../data-injector.module';
import { EnvService } from '../env/env.service';
// @dynamic
@Injectable()
export class RemoteDataService<T> {
private env = DdataInjectorModule.InjectorInstance.get(EnvService);
public type: new () => T;
constructor(
model: T,) {
this.http = DataInjectorModule.InjectorInstance.get(HttpClient);
}
// ...
}
因此RemoteDataService
的{{1}}属性没有受到影响,但是服务可以通过constructor
访问环境变量。
在大多数情况下,角度DI是在library(shiny)
ui <- fluidPage(
# here
actionButton("button","Faça Login e assine")
)
server <- function(input,output,session) {
observeEvent(input$button,{
## do something
})
}
shinyApp(ui,server)
中完成的。正如您这样编写构造函数
constructor
Angular认为您正在尝试注入constructor(
model: T,)
。您应该将所有想要的东西注入到构造函数中
T
,但是请确保正确提供了env。甚至出于这个原因最好使用constructor( @Inject('env') private environment) {}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。