【问题标题】:Angular: dependency injection for different routeAngular:不同路线的依赖注入
【发布时间】:2020-11-17 05:54:37
【问题描述】:

我有一个 Angular 应用程序,它具有按功能模块的架构。我有一个OrdersModule,其中包含ListOfOrdersDetailOfOrderEditOfOrder 等组件

所有这些组件都需要在构造函数中使用OrdersApiService,这基本上是一个使用REST API 后端通过HTTPS 提供CRUD 操作的简单服务。

OrdersModule 与一个名为 Order

的实体一起使用

我收到了一个功能请求,我将在其中实施新实体,称为草稿订单。实际上,Draft OrderOrder 之间没有区别(它们包含完全相同的属性,它们以相同的方式创建)但它们必须以不同的方式存储,它们有不同的 API 端点(myApi.com/orders vs myApi.com/draft-orders

最简单的方法(从花费时间的角度来看)是将订单复制/粘贴到新模块。但是,我希望避免代码重复,所以这种方法应该适合我:

{
    path: 'orders',
    loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule)
},

{
    path: 'draft-orders',
    loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule)
},

现在我需要根据路由向组件注入不同的服务。我知道解决方法

{
    path: 'orders',
    loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule),
    data: {
      type: 'orders'
    }
},

{
    path: 'draft-orders',
    loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule),
    data: {
      type: 'draft-orders'
    }
},

并在服务中使用ActivatedRoute:

constructor(
    private route: ActivatedRoute,
  ) {
    this.type = this.route.snapshot.data['type'];
  }

   getOrders() {
     return this.http.get('myApi.com/' + this.type);
   }

有没有办法注入整个服务?

谢谢!

【问题讨论】:

    标签: angular typescript angular-dependency-injection


    【解决方案1】:

    第一个解决方案

    如果你想走硬路线,可以使用useFactory method解决问题。

    实现api服务并将api端点存储到服务的只读字段中。使用useFactory 方法和baseUrl 属性注入所有需要的服务。

    @Injectable()
    export class ApiService {
      constructor(
        private logger: LoggerService,
        private userService: UserService,
        private readonly baseUrl: string
      ) {}
    
      getUrl() {
        return this.baseUrl;
      }
    }
    

    之后你需要创建provider factory,你将根据一些信息决定使用哪个url(我在这个中使用了当前路由)

    @NgModule({
      imports: [RouterModule.forChild([{ path: "", component: OrderComponent }])],
      providers: [
        {
          provide: ApiService,
          // List of needed dependecies
          deps: [LoggerService, UserService, Router],
          // Dependencies order should be preserved
          useFactory: (
            logger: LoggerService,
            userService: UserService,
            router: Router
          ) => {
            const isDraft = router.url.includes("draft");
    
            return new ApiService(
              logger,
              userService,
              isDraft ? OrdersUrl.DRAFT : OrdersUrl.COMMON // inject ORDERS_URL
            );
          }
        }
      ],
      declarations: [OrderComponent]
    })
    export class OrderModule {}
    

    这样你就不会有重复的代码了。

    Codesandox

    第二种解决方案

    更简单的方法是决定在 api 服务中正确使用哪个 url。例如,基于当前路线。

    【讨论】:

    • 谢谢你!这给了我一个方向。我目前正在研究一种模块拆分。稍后我将更新我的原始帖子。谢谢!
    猜你喜欢
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    相关资源
    最近更新 更多