question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot inject parent directive/component from a directive placed inside template

See original GitHub issue

I’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:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
rusevcommented, Dec 28, 2016

@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?

1reaction
rusevcommented, Dec 17, 2016

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 the TemplateRef 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:

  • allow createEmbeddedView to accept injector as another parameter
  • change the behavior by inferring the injector from the ViewContainerRef 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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to inject a parent component into a shared directive ...
Create a module and put your directive into the declarations of the shared ... 1) Define a token that will be used for...
Read more >
Hierarchical injectors - Angular
The next parent injector in the hierarchy is the NullInjector() , which is the top ... To mark the locations of where the...
Read more >
How to Pass an Element Reference Down Through a ...
With that in place, we then just Dependency Inject the directive into our downstream modal component and create a property on the component...
Read more >
Here is how to get ViewContainerRef before @ViewChild ...
All dynamic components are inserted into a specific place in the template using ... Well, a directive can inject a parent component and...
Read more >
Angular ng-template, ng-container and ngTemplateOutlet
The ng-template directive and ngIf · the element onto which the structural directive ngIf was applied has been moved into an ng-template ·...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found