Cannot inject parent directive/component from a directive placed inside template
See original GitHub issueI’m submitting a … (check one with “x”)
[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior Directive/component inside a template cannot inject the directive/component in which that template is materialized. Currently the button directive (in the bellow plnkr) can only inject the table component, i.e the component in which the template is defined.
Expected behavior To be able to inject cell component in which the template is materialized multiple times.
Minimal reproduction of the problem with instructions https://plnkr.co/edit/6TGOdo5wj0GvQbUsitKv?p=preview
What I expect is to be able to inject cell directive (or a service which is provided from it) inside the button directive.
What is the motivation / use case for changing the behavior? The use case is that the template is materialized multiple times in different context and all the directives/components inside that template should be able to infer that context based on where the template is materialized.
A concrete scenario is where I have built-in command directives. I can use them inside data-bound component and that directives should infer a context, such as: item index, data item etc., by itself.
I hope that make sense to you. Thank you for your cooperation.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:5 (1 by maintainers)
@tbosch Unfortunately I was expecting such answer.
However what do you think about allowing
createEmbeddedView
to accept injector as another parameter? This will not hurt the performance, right?After spending couple of days investigating this issue I can now say that I understand why it is happening.
createEmbeddedView
calls_parentView
which is passed to theTemplateRef
constructor when initialized.However this still makes me think that there is a conceptual issue here. My mental model for templates is as follows - a template is a block of code defined on one place and instantiated on another or even on multiple other places. That’s why the context as well as the injector for that template should depend on where it is initialized. This the only places/places where that template has meaning.
In our case the parent view is where the template is defined. not where initialized. An there isn’t any mechanism provided by the framework to change the injector instance. At least there isn’t public API for this.
I’ve tried implementing this scenario by using
createComponent
instead. There I can provide injector instance, but the behavior remains the same due to same reasons - template parent view is where template is defined.What I see as an options:
createEmbeddedView
to accept injector as another parameterViewContainerRef
in which the template will be inserted, not from the_parentView
If you don’t agree with all the above could you show how should we handle such cases. Is this scenario possible to implement?
While researching this issue I came across this explanation by Miško which seems to confirm my assumptions.
Sorry if I’m being too wordy, but this issue is really important to me and I’m trying to provide as much context as I can.