7

@Input在属性中注入“服务”依赖项是一种好习惯吗?此上下文中的服务不是在根级别管理的单例实例,而是接口的不同实现的多个实例。

考虑以下示例:在 Angular 库中,ShapeComponent 依赖于 ShapeService(接口)。

零件

@Component({
  selector: 'ex-shape',
  templateUrl: '..',
})    

export class ShapeComponent {
   constructor(shapeServiceCtor: ShapeService)
    
   @Input shapeServiceInput: ShapeService;
}

解决依赖关系的一种简单方法是设置输入属性,如下面的代码所示。

<ex-shape [shapeServiceInput]="rectangleShapeService" />
<ex-shape [shapeServiceInput]="ellipseShapeService" />
<ex-shape [shapeServiceInput]="polygonShapeService" />

上述方法是否适用于解决组件中的依赖关系?

如果使用输入属性方法,那么服务/依赖项必须以相同的方式传播到子组件。这种方法的缺点是父组件必须接受所有依赖项作为输入属性。

是否有任何推荐的方法来在库级别注入和作用域依赖项?

4

6 回答 6

6

此时您并没有真正使用 Angular 的依赖注入,在您的情况下,我不确定这是好是坏。

如果 ShapeComponent 无法知道它正在使用哪个服务实例,并且任何时候调用它都需要传递一个任意实例,这应该没问题。

如果 ShapeComponent 的父级将始终传递相同的服务实例,则父级可以将其包含在其providers数组中,然后子级 ShapeComponents 将使用相同的实例。

Angular 的文档有一些关于 DI 层次结构的更详细信息 https://angular.io/guide/hierarchical-dependency-injection

您的调用constructor(shapeServiceCtor: ShapeService)也会导致一些混乱,因为组件将同时注入一个 DI 和另一个(或可能相同)实例@Input

于 2020-07-07T17:04:23.793 回答
1

这可能适用于您的情况:

@Component({
  selector: 'ex-shape',
  templateUrl: '..',
})    
export class ShapeComponent {
   // change the type to any since any service will be comping as input
   private shapeServiceCtor: any;

   constructor(
       private injector: Injector // injector to inject incoming services
   ) {}

   // type as any
   @Input shapeServiceInput: any;

   ngOnInit() {
       // this will inject the service
       this.shapeServiceCtor = this.injector(shapeServiceInput);
   }
}
于 2020-07-13T22:51:35.023 回答
0

从 @Injectable () 装饰器中删除参数。它确保不在根级别提供服务:

@Injectable()
export class ShapeService{

您可以在组件级别声明服务,并且可以将服务照常注入任何子组件。子组件将获得与父组件相同的实例。

在 ShapeComponent 中,您可以在 @Component 装饰器中提供服务:

@Component({
  selector: 'ex-shape',
  templateUrl: '..',
  providers:  [ ShapeService ]
})    

export class ShapeComponent {
   constructor(private shapeServiceCtor: ShapeService)

这假定您需要为每个 ShapeComponent 提供一个新的 ShapeService 实例。

于 2020-07-12T20:13:21.017 回答
0

你应该设置为providedIn装饰器。true@Injectable

您的想法是使用单例,并且可以通过设置providedIn为来实现单例注入true

然后你不需要@Input深入使用装饰器,你可以简单地导入服务并在你要使用的组件中使用它。

所以格式应该是这样的。

@Injectable({
    providedIn: true
})
export class SomeService {
 ...
}
于 2020-07-10T00:59:22.903 回答
0

“注入”这样的服务是行不通的。您将必须传递所述服务的实例。相反,尝试创建多个形状组件,如果它们共享功能,则让它们扩展基本组件或使用服务在它们之间共享。

于 2020-07-07T18:54:39.483 回答
0

@Input 和@Output 用于通信,一个组件与另一个组件之间的通信。@Input 会将我们的变量暴露给组件外部。依赖注入是一个不同的概念,在依赖注入中,我们在构造函数中注入组件和内置类,这将为我们提供。@Input 绝对不是正确的方法。

于 2020-07-13T04:24:02.487 回答