18

I am trying to build my own Modal component, that I would be able to reuse throughout my Angular2 Apps. I am considering different approaches, and I am wondering if it is possible to create @Component that also serves as @Injectable? I am considering this, as I want to build a template for the Modal, and keep it in one place.

Thanks

alegrowski
  • 261
  • 2
  • 3
  • 8

1 Answers1

22

A component is injectable by default @Component() (or @Directive()) includes @Injectable().

Don't expect to get a specific instance of a component injected. This works for example with constructor(@Host() private parentComponent) where DI lookup is limited to parent injectors up to the injector of the host element.

Normally for your use case DynamicComponentLoader is used which only accepts the type of a component, not an instance. Dependency injection would just create an instance of the components class but not for example the associated view.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • So can I inject it in constructor? – alegrowski Apr 08 '16 at 08:30
  • I updated my answer. I don't think using DI will buy you much for your use case. – Günter Zöchbauer Apr 08 '16 at 08:33
  • Gunter, I've always been under the impression that constructor-injection of a component type only works when there exists a parent of that type for the component trying to inject it, in which case the instance injected is the instance of the nearest parent of that type (and that this serves the (very useful) purpose of allowing components to inject arbitrarily-typed parents). Is this impression not correct? – drew moore Apr 08 '16 at 08:45
  • 2
    @drewmoore Exactly, that's what I tried to explain in my answer (2nd paragraph). – Günter Zöchbauer Apr 08 '16 at 08:46
  • @GünterZöchbauer, should I just initialize new comopnent like : var modal = new Modal() ? – alegrowski Apr 08 '16 at 08:49
  • 1
    If you want to create a new instance of a component at runtime use [DynamicComponentLoader](https://angular.io/docs/ts/latest/api/core/DynamicComponentLoader-class.html) there are lots of related questions here on SO for more details. – Günter Zöchbauer Apr 08 '16 at 08:54
  • 1
    Gunter, correct me if I'm a wrong, but I believe `@Parent` has been removed from the API, and that `@Inject` should be used in its place here. – drew moore Apr 14 '16 at 06:42
  • 1
    `@Inject()` and `@Parent()` are two different things. `@Inject()` allows you to specify a key for DI that deviates from the type of the constructor parameter. It seems you are right about `@Parent`. `@Host()` seems to be the closest to the removed `@Parent()`. Thanks a lot for pointing it out. I'll update my answer. The only information I found about it was the comment to http://stackoverflow.com/q/31834527/217408 – Günter Zöchbauer Apr 14 '16 at 06:59
  • Interesting - you're right about this not being well-documented yet... [Look at this, though](http://stackoverflow.com/a/34540842/1988693) - at some point at least, `@Inject` was serving something of an overloaded purpose in this context. My understanding was that `@Inject` would find the appropriately-typed parent anywhere in the hierarchy above the target, while `@Host` would only look at the immediate host element. This doesn't seem to be backed up by the documentation though – drew moore Apr 19 '16 at 01:35