<p dir="auto">We have a library of components for angular that we are currently migrating to Angular 2. We have a container that injects content using <code class="notranslate">ng-content</code>. We would like to have a child component that injects the parent if you nest it inside of the parent, like so:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;parent&gt;
    &lt;child&gt;&lt;/child&gt;
&lt;/parent&gt;"><pre class="notranslate"><code class="notranslate">&lt;parent&gt;
    &lt;child&gt;&lt;/child&gt;
&lt;/parent&gt;
</code></pre></div>
<p dir="auto">This works beautifully in angular 2. However, since are in the process of migration, we would like to use the ngUpgrade adapter for this. The dependency injection seems to fail if the parent and child are specified in an angular 1 context. Any insights on this issue? Is this something that is going to be supported in the ngUpgrade adapter?</p>
<p dir="auto">I have a working plunker that illustrates the problem:</p>
<p dir="auto"><a href="http://plnkr.co/edit/9qb6ZK9SpJyrWoJDEFEj?p=preview" rel="nofollow">http://plnkr.co/edit/9qb6ZK9SpJyrWoJDEFEj?p=preview</a></p>
<p dir="auto">In both cases, the template includes a parent with the child <code class="notranslate">transcluded/projected</code> into it. The child tries to inject the parent and then calls a function on it when you press the button. The ng2 example works, but not the ng1/ngUpgrade one.</p>
<p dir="auto">According to the docs, making a directive that listens for events on the host element is like so:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Directive({
  selector: 'input',
  hostListeners: {
    'change': 'onChange($event)',
    'window:resize': 'onResize($event)'
  }
})
class InputDirective {
  onChange(event:Event) {}
  onResize(event:Event) {}
}"><pre class="notranslate">@<span class="pl-smi">Directive</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">selector</span>: <span class="pl-s">'input'</span><span class="pl-kos">,</span>
  <span class="pl-c1">hostListeners</span>: <span class="pl-kos">{</span>
    <span class="pl-s">'change'</span>: <span class="pl-s">'onChange($event)'</span><span class="pl-kos">,</span>
    <span class="pl-s">'window:resize'</span>: <span class="pl-s">'onResize($event)'</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">class</span> <span class="pl-smi">InputDirective</span> <span class="pl-kos">{</span>
  <span class="pl-en">onChange</span><span class="pl-kos">(</span><span class="pl-s1">event</span>:<span class="pl-smi">Event</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
  <span class="pl-en">onResize</span><span class="pl-kos">(</span><span class="pl-s1">event</span>:<span class="pl-smi">Event</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This seems like it could be streamlined:</p>
<ul dir="auto">
<li>The listeners are registered far away from where the handlers are defined</li>
<li>The registration duplicates a) the method names and b) arguments.</li>
<li>The registration uses strings which makes obfuscation and refactoring more difficult.</li>
<li>You can listen for global events, too (seems odd that the <strong>host</strong>Listener object lets you do this)</li>
<li>Listening for global events depends on a magic string prefix of "window:" (or "document:" or "body:", implied by the docs)</li>
</ul>
<p dir="auto">Here's a possible alternative:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Directive({
  selector: 'input'
})
class InputDirective {
  @HostListener('change')
  onChange(event: Event) {}

  @WindowListener('resize')
  onResize(event: Event) {}
}"><pre class="notranslate">@<span class="pl-smi">Directive</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">selector</span>: <span class="pl-s">'input'</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">class</span> <span class="pl-smi">InputDirective</span> <span class="pl-kos">{</span>
  @<span class="pl-smi">HostListener</span><span class="pl-kos">(</span><span class="pl-s">'change'</span><span class="pl-kos">)</span>
  <span class="pl-en">onChange</span><span class="pl-kos">(</span><span class="pl-s1">event</span>: <span class="pl-smi">Event</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

  @<span class="pl-smi">WindowListener</span><span class="pl-kos">(</span><span class="pl-s">'resize'</span><span class="pl-kos">)</span>
  <span class="pl-en">onResize</span><span class="pl-kos">(</span><span class="pl-s1">event</span>: <span class="pl-smi">Event</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This doesn't suffer from any of the problems listed above.</p>
<p dir="auto">You can imagine a similar streamlining for properties. Currently you write:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Directive({
  selector: '[dependency]',
  properties: {
    'id':'dependency'
  }
})
class Dependency {
  id:string;
}"><pre class="notranslate">@<span class="pl-smi">Directive</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">selector</span>: <span class="pl-s">'[dependency]'</span><span class="pl-kos">,</span>
  <span class="pl-c1">properties</span>: <span class="pl-kos">{</span>
    <span class="pl-s">'id'</span>:<span class="pl-s">'dependency'</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">class</span> <span class="pl-smi">Dependency</span> <span class="pl-kos">{</span>
  <span class="pl-c1">id</span>:<span class="pl-smi">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">But using decorators you could write:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Directive({
  selector: '[dependency]',
})
class Dependency {
  @Property('dependency')
  id:string;
}"><pre class="notranslate">@<span class="pl-smi">Directive</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">selector</span>: <span class="pl-s">'[dependency]'</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">class</span> <span class="pl-smi">Dependency</span> <span class="pl-kos">{</span>
  @<span class="pl-smi">Property</span><span class="pl-kos">(</span><span class="pl-s">'dependency'</span><span class="pl-kos">)</span>
  <span class="pl-c1">id</span>:<span class="pl-smi">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">I find it a whole lot easier to understand this, not needing to remember constantly what the left and right hand side of the configuration means. E.g. for <code class="notranslate">{ 'id': 'dependency' }</code> I cannot tell easily which one of 'id' or 'dependency' is the JS class property and which is the DOM element property. I constantly get this confused in Angular 1, too, with the scope config. Hopefully we can eliminate this rough edge in Angular 2...</p>