如何在Angular TypeScript项目的抽象类中使用回退服务

huangapple go评论111阅读模式
英文:

How to use fallback services in abstract class of angular-typescript project

问题

我正在进行TypeScript-Angular项目的开发,我创建了一个如下所示的基类:

export abstract class MyClass {
    constructor(private toastService?: ToastService) {}
    ...
}

我在另一个类中扩展了MyClass,如下所示:

export class AcademyDraftListService extends AssessmentsDataService{
    constructor() {
        super()
    }
}

现在,如果我在父类中不传递toastService,那么在子类中它将始终为null。我可以实现其他方法来在父类不传递服务时使用备用服务吗?

我知道对于变量,我们可以在父类中像这样做:

constructor(private myVar?: ToastService='some value')

但在Angular中如何实现同样的功能来处理服务呢?

英文:

Im working on typescript-angular project, where i have created a base class as follow:

export abstract class MyClass {
    constructor(private toastService?: ToastService) {}
    ...
}

I have extended MyClass in another class as bellow:

export class AcademyDraftListService extends AssessmentsDataService{
    constructor() {
        super()
    }
}

Now if i don't pass toastService from parent then, in child it's always null. Can i implement any other approach to use fallback service if parent class does not pass the service?

I knew for variables we can do something like this in parent:

constructor(private myVar?: ToastService='some value')

But how to achieve same thing for Services in angular?

答案1

得分: 1

Angular不会将任何服务注入到您的父类中。您也必须将其添加到子类的构造函数中,并将其传递到父类的构造函数中。

export abstract class MyParentClass {
    constructor(private myService?: MyService) {}
    ...
}

export class MyClass extends MyParentClass {
    constructor(myService?: MyService) {
      super(myService);
    }
    ...
}

此外,没有所谓的回退服务。虽然您可以自己创建服务的新实例作为默认值,但您将不会使用Angular的依赖注入,这可能会导致问题,尤其是如果服务还具有依赖关系。

export abstract class MyParentClass {
    constructor(private myService: MyService = new MyService()) {}
    ...
}

或者,您可以尝试使用 Angular的注入器 来获取该服务,尽管您还需要将其注入到您的子类中或创建一个新实例。

最佳做法是在构造函数中从子类传递该服务到父类中。

英文:

Angular will not inject any services to your parent class. You have to add it to the constructor of your child class too and pass it to the constructor of your parent class.

export abstract class MyParentClass {
    constructor(private myService?: MyService) {}
    ...
}

export class MyClass extends MyParentClass {
    constructor(myService?: MyService) {
      super(myService);
    }
    ...
}

Also there is nothing like a fallback service. While you can create a new instance of the service as default value by yourself, you won't be using Angulars dependency injection, which might cause problems or be complicated if the service has also dependecies.

export abstract class MyParentClass {
    constructor(private myService: MyService = new MyService()) {}
    ...
}

Alternatively, you can try using Angulars Injector to fetch the service, although you'll also need to inject it into your child class or create a new instance.

Best practices would be to pass the service from the child class to the parent class in the constructor.

答案2

得分: 1

为了直接回答你,在Angular 16中,你可以使用inject函数:

export class MyBaseClass {
  private toaster = inject(ToasterService);
}

不需要在构造函数中注入它,也不需要通过super调用来注入。

现在,就这个问题提供我的意见:在Angular中,你应该避免扩展你的类。Angular使用装饰器,不需要扩展,否则可能会导致一些奇怪的错误。在Angular中应该使用正确的方法,即组合(实现接口如OnInit)或依赖注入。

所以,不要创建一个基类,而是创建一个可注入的服务,并像这样使用它:

export class MyBaseClass {
  doSomething() {}
}

export class MySubClass {
  private base = inject(MyBaseClass);
  doSomething = this.base.doSomething.bind(this.base);
}
英文:

To answer to you directly, in Angular 16 you have the inject function :

export class MyBaseClass {
  private toaster = inject(ToasterService);
}

Not in the constructor = No need to inject it through the super call.

Now, to give my two cents on the issue : in Angular, you should avoid extending your classes. Angular works with decorators, that are not extended, and it can lead to pretty strange errors. The correct approach to use in Angular is composition (implementing interfaces like OnInit), or dependency injection.

So instead of creating a base class, create an injectable service and use it like so :

export class MyBaseClass {
  doSomething() {}
}

export class MySubClass {
  private base = inject(MyBaseClass);
  doSomething = this.base.doSomething.bind(this.base);
}

huangapple
  • 本文由 发表于 2023年6月22日 15:01:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76529321.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定