Angular 角度动态模块提供程序
我有一个模块,它应该根据路由器路径注入服务,例如。 对于带有Angular 角度动态模块提供程序,angular,dependency-injection,module,Angular,Dependency Injection,Module,我有一个模块,它应该根据路由器路径注入服务,例如。 对于带有/demo的路径,它应该注入DemoService,对于没有/demo的路径,它应该提供用户服务 我如何实现这样的功能 当然,我可以注入这两种服务,并在模块本身中确定它是否应该使用DemoService或UserService,但这样模块就不能在其他应用程序中重用 为提供者定义一个类型,比如说,在您的情况下,您可以有一个类提供者,比如工厂类,例如 在消费者组件中,您现在可以通过ServiceFactory访问特定服务,该服务应提供适当的
/demo
的路径,它应该注入DemoService
,对于没有/demo
的路径,它应该提供用户服务
我如何实现这样的功能
当然,我可以注入这两种服务,并在模块本身中确定它是否应该使用DemoService
或UserService
,但这样模块就不能在其他应用程序中重用
ServiceFactory
访问特定服务,该服务应提供适当的服务希望,你已经想到了…谢谢你的回答,但我不是这个意思。我试图避免任何关于模块应该在模块本身中使用哪个服务的逻辑。想象一下,您希望将其作为npm(我不想这样做,但我希望这样做)。模块只需要获取数据和传递数据,不应该决定使用哪个服务。或者我对这整件事的想法是错误的?在我提供的示例中,您可以将定义有关
localation.path
的服务的逻辑放在根模块或模块层次结构中的任何其他模块中,这些模块应该使用实际的DemoService
或UserService
。因此,模块消费者将不了解其将使用的最终服务以及将使用父模块提供的服务。问题是,无论如何,定义最终服务的逻辑应该存在于某个地方……另一种可行的方法是1。将您的路径服务
正确的配置放入环境.ts中
就像服务:{locationPath:'demo',servicePath:'./demo.service.ts'}2一样。为AppModule
定义ngDoBootstrap`方法,`并从environment.ts
3获取服务路径。使用import动态导入类(environment.service[servicePath)
4.创建注入器并添加加载的类。5.将注入器连接到ngDoBootstrap
方法中的AppComponent。就个人而言,我自己还没有尝试过,但从理论上讲,它应该可以工作……我一直在尝试实现您的第一个解决方案,但我认为这个.serviceFactory.activeService.subscribe()有问题
在组件构造函数中,我得到一个类型错误:无法读取未定义的属性“subscribe”
错误。我还尝试了getService()但是这里也不走运,这个方法是干什么的?哎呀,我的坏消息……你收到了一个TypeError
,因为activeService
是一个静态属性。我更新了代码,现在应该可以用了,基本上,我定义了activeService
属性和getService()
方法是公共的,而不是静态的……因此,如果您在代码中更改这些方法,那么这一行this.serviceFactory.activeService.subscribe()
将起作用。
abstract class DataService {
abstract doSomething(): void;
}
class FactoryService {
activeService = new BehaviorSubject<DataService>();
getService(): Observable<DataService> {
return this.activeService.asObservable();
}
}
class DemoService extends DataService {
doSomething(): void {
console.log('DemoService');
}
}
class UserService extends DataService {
doSomething(): void {
console.log('UserService');
}
}
providers: [{
provide: FactoryService,
useFactory: (route: ActivatedRoute) => {
const factoryService = new FactoryService();
const url = route['_routerState'].snapshot.url;
url.startsWith('/demo/')
? factoryService.activeService.next(new DemoService())
: factoryService.activeService.next(new UserService());
return factoryService;
}
deps: [ActivatedRoute]
}],
constructor(private factoryService: FactoryService) {
this.factoryService.activeService.subscribe((activeService: DataService) => {
// Here you can now do stuff with an proper service
});
}