用Angular 4注入接口 [英] Inject an Interface with Angular 4

查看:80
本文介绍了用Angular 4注入接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个通用的 DeleteableConfirmationComponent ,它将允许我显示一个确认对话框并从任何实现了 Deleteable的注入服务中调用 delete 方法背面.

I'm trying to create a generic DeleteableConfirmationComponent that will allow me to show a confirmation dialog and invoke the delete method from any injected service implementing a Deleteable infterface.

为此,我创建了此接口:

To do so, I've created this Interface:

export interface Deleteable {
  delete(object);
}

并且我有一个实现它的服务:

and I have a service that implements it:

@Injectable()
export class LocalityService implements Deleteable {
  delete(locality): Observable<Locality> {
    // Delete logic.
  }
}

对于 DeleteableConfirmationComponent ,我尝试使用构造函数注入服务:

For the DeleteableConfirmationComponent, I've tried to inject the service using constructor:

export class DeleteableConfirmationComponent {
  constructor(
    public dialog: MdDialogRef<DeleteableConfirmationComponent>,
    @Inject(MD_DIALOG_DATA) public data: any,
    private service: Deleteable
  ) {}

  delete() {
    this.service.delete(this.object)
                .subscribe(() => {
                  this.dialog.close();
                });
  }
}

但不幸的是,我遇到一个错误,提示它无法解析DeleteableConfirmationComponent的所有参数.

but unfortunately, I've got an error saying it can't resolve all parameters for DeleteableConfirmationComponent.

目前,我正在使用对话框数据选项,以传递服务:

For now, I'm using the dialog data options, in order to pass my service:

confirmDelete(locality) {
  this.dialog.open(DeleteableConfirmationComponent, {
    data: {
      service: this.localityService
    }
  });
}

但是它感觉很脏,并且在我想强制实现 Deleteable 接口的服务时,确实允许注入任何类型的服务.

but it feels dirty and does allow any kind of service to be injected while I want to force service that implement the Deleteable interface.

我原本以为我可以使用抽象类更好,但是我更喜欢构图而不是继承.

I was thinking I could probably be better going with an abstract class but I'm more a fan of composition over inheritance.

有什么想法或最佳做法建议吗?

Any idea or best practice advise?

推荐答案

如注释中所述,您可以将接口转换为抽象类:

As mentioned in the comments, you can convert your interface to an abstract class:

export abstract class Deleteable {
  abstract delete(object);
}

然后在您的提供程序中将其映射到真实类:

Then in your providers you can map it to the real class:

providers: [{ provide: Deleteable, useValue: new LocalityService() }]

您可能不喜欢这种方法,因为现在看来 LocalityService 必须扩展 Deleteable .但是,如果 LocalityService 需要扩展其他类怎么办?不允许多重继承:

You may not like this approach, because it seems like now LocalityService must extend Deleteable. But what if LocalityService needs to extend some other class? Multiple inheritance is not allowed:

// Error: Classes can only extend a single class
export class LocalityService extends OtherClass, Deleteable { }

或者您可能根本不喜欢 Deleteable 现在将出现在 LocalityService 的原型链中的事实:

Or you may simply not like the fact that Deleteable will now show up in the prototype chain of LocalityService:

export class LocalityService extends Deleteable {
  delete(locality): void {
    // Returns true
    alert(this instanceof Deleteable);
  }
}

但是,如此答案中所示,TypeScript允许您将类视为接口.因此,您可以将 implements 与抽象类一起使用.

However, as shown in this answer, TypeScript allows you to treat a class like an interface. So you can use implements with an abstract class.

export class LocalityService extends OtherClass implements Deleteable {
  delete(locality): void {
    // Returns false
    alert(this instanceof Deleteable);
  }
}

因此,出于所有意图和目的,您的抽象类现在的行为就像一个接口.它甚至不会出现在原型链中.

So for all intents and purposes, your abstract class is now behaving like an interface. It won't even show up in the prototype chain.

这篇关于用Angular 4注入接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆