如何提供在Angular4中使用泛型的服务?

投票

我注意到我的项目有很多解析器服务,尽管它们与不同的实体和存储库一起使用时仍承载相同的代码。因此,我面临着使用泛型将它们简化为单个解析器服务的挑战:

@Injectable()
export class DetailResolver<T, R extends Repository<T>> implements Resolve<T> {

  constructor(private repositoryService: R, private router: Router) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> {
    // use repositoryService to resolve this route
  }
}

可以指定实体类型T和存储库类型R。但是我在使用此服务时遇到了麻烦:

const appRoutes: Routes = [
  // other routes
  {
    path: ':id',
    component: MessageEditComponent,
    resolve: {
      message: DetailResolver<Message, MessageService>
    }
  }
];

@NgModule({
  imports: [
    RouterModule.forChild(appRoutes)
  ],
  exports: [
    RouterModule
  ],
  providers: [
    DetailResolver<Message, MessageService>
  ]
})

一旦在DetailResolver<Message, MessageService>编译器中指定了通用类型,就希望我创建一个实例:

DetailResolver类型为type的值不可调用。您是说要包括新内容吗?

我对angular4 DI内部并不十分熟悉。谁能描述出什么问题了,这个问题有解决方案吗?我正在使用角度4.3。

mar客

当您向喷射器注册提供程序时,DI系统将使用该令牌(或其他可能被视为的令牌)来维护每次请求依赖项都引用的令牌提供者映射。

令牌通常是唯一且具有象征性的对象,因此泛型的概念在该领域直接冲突,恰恰是因为令牌将用作密钥泛型是设计时的工件,这是另一种说法,即泛型将从生成的JavaScript中消失,因此不会将其类型信息留给Angular在运行时查找。出于相同的原因,TypeScript接口也不是有效的令牌。

抽象类

我的第一个选择是使用abstract抽象类在这里解决了两个问题:1)尽管它们不能直接实例化,但与接口不同,它们可以包含实现细节,因此可以编译为Javascript。2)您可以通过基于扩展的体系结构获取DI令牌,这可能对您的体系结构非常有效。

在您的情况下,您可以执行以下操作:

@Injectable()
export abstract class DetailResolver<T, R extends Repository<T>> implements Resolve<T> {...}

@Injectable()
export class MessageResolver extends DetailResolver<Message, MessageService> {...}

然后,NgModule您将通过以下方式提供它:

providers: [{ provide: DetailResolver, useClass: MessageResolver }]

注入令牌

另一个选择是使用InjectionTokenOpaqueToken在Angular 4.0之前称为s)。InjectionTokens是专门用作DI令牌的对象;但是,与它们的前身不同OpaqueToken,他们需要输入将要注入的值的类型。

const MESSAGE_RESOLVER = new InjectionToken<DetailResolver<Message, MessageService>>('MESSAGE_RESOLVER');

您会注意到,在创建InjectionToken实例时可以提供类型,以使编译器始终支持您。当您在中添加提供程序时,将强制执行该操作NgModule

providers: [{ provide: MESSAGE_RESOLVER, useClass: MessageResolver }]

值得注意的是,useClass在技​​术上并不需要 提供相应内容时,其他任何替代方法(例如useValue或)useFactory在此处均有效。

希望这会有所帮助,并对此事提供一些澄清!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何提供在TeamCity构建步骤中使用的程序集版本

如何使用angular4在获取服务呼叫中传递语言环境

如何在angular4中使用TemplateRef的createEmbeddedView方法?

如何在Angular4中使用Chart.js?

如何在 angular4 中使用 node_modules 中的 svg 图标集包?

如何在表Angular4中使用唯一ID动态添加html行

如何在Angular4中使用img标签迭代json数据

如何在angular4的ngif中使用'or'语句?

如何在C#中的泛型类中使用泛型类的对象?

在Angular4中使用网络套接字吗?

在 Angular 路由中使用泛型

Camel Bindy:提供在spring.xml中使用的类

在Angular 4中的服务中使用Router

如何在SqlDataReader中使用泛型

如何在泛型中使用括号?

如何在Scala中使用泛型

如何在 Java 中使用泛型

如何在代码中返回数据表,以供在bokeh中使用?

如何在Angular4中使用Scss将样式设置为ng-select框

在 Spring 中使用泛型生成服务

如何在Angular 4中使用提供程序模拟组件?- 单元测试

如何在Angular 4中组件的HTML模板中的服务中使用BehaviorSubject类?

C#中的泛型如何提供源代码保护

如何为使用泛型 impl 提供适当的类型?

在angular4中使用mydatepicker在输入框中设置日期

Angular4为存在并正在公开提供服务的json数据提供404

如何使用泛型OwinCommunicationsListener将依赖注入添加到无状态服务中

如何在功能组件的React中的props中使用泛型?

如何在C#中的泛型类型参数中使用Switch ... Case?