7

Angular app structure:

<app><div content><a href="#" (click)="show()">click me</a></div></app>

Content component template:

<ng-content></ng-content>

Content component has public method show(), but when i click this link i get:

Error: EXCEPTION: Error during evaluation of "click"
ORIGINAL EXCEPTION: TypeError: l_context.show is not a function
ORIGINAL STACKTRACE:
anonymous/ChangeDetector_AppComponent_0.prototype.handleEventInternal@http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js line 10897 > Function:207:13
AbstractChangeDetector</AbstractChangeDetector.prototype.handleEvent@http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8788:17

Basically i want to reuse page markup and put listeners on existing dom, i don't want to create additonal templates or components. Probably i'm missing something obvious.

Planker

Community
  • 1
  • 1
kemsky
  • 14,727
  • 3
  • 32
  • 51

1 Answers1

7

show() would resolve to the parent component of <app> and because it looks like <app> is the root component, there is no parent.

I guess the bug here is that Angular even tries to bind to the click event. I got the impression that <ng-content> isn't supported at all on the root component.

See also https://github.com/angular/angular/issues/1858 (https://github.com/angular/angular/issues/6046)

Update

<h1>Angular</h1>
<div content #contentRef>
    <ui>
        <li><a href="#" (click)="contentRef.show($event)" class="link" button>link 1</a></li>
        <li><a href="#" (click)="contentRef.show($event)" class="link" button>link 2</a></li>
        <li><a href="#" (click)="contentRef.show($event)" class="link" button>link 3</a></li>
    </ui>
</div>

bindings are resolved within the component where they are declared. In the above example I explicitly redirected the reference to the ContentComponent by creating a template variable #contentRef on the target element and referring it when defining the click handler (click)="contentRef.show($event)".

Even though the content is "passed" to another component using <ng-content> doesn't mean the scope changes. <ng-content> is only a projection - the elements are displayed at a different place is all, they are still "owned" by the component where they are added originally.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • opps, my fault, sample code is incorrect, one moment. – kemsky Feb 23 '16 at 10:42
  • there is additional content component under app which declares template with ng-content. I noticed that angular uses app context instead of content. – kemsky Feb 23 '16 at 10:48
  • Hmm, doesn't really change anything in my opinion. The parent "scope" is still the parent of the root component. – Günter Zöchbauer Feb 23 '16 at 10:50
  • Thank you for your help, i've updated description, i wish was not rushing. App contains component with ng-content template, but listeners are resolved in app. – kemsky Feb 23 '16 at 11:00
  • That would only work if `click me` would be inside the template of `ContentComponent`. If `` were inside the template of an Angular component you would be able to `` (not tried exactly like that myself yet though) – Günter Zöchbauer Feb 23 '16 at 11:03
  • But isn't it inside? I assumed that if component has template with ng-content then component is parent of ng-content, so everything should also be resolved against this component. – kemsky Feb 23 '16 at 11:12
  • It's inside the tag, but not inside the template, which means the string you pass to `template: "..."` or in the the file passed to `templateUrl: "someFile"`. Can you please create a Plunker that shows exactly what you are trying? – Günter Zöchbauer Feb 23 '16 at 11:25
  • added planker sample. – kemsky Feb 23 '16 at 12:00
  • Seems this is what you want then http://plnkr.co/edit/15Fe1mByb5jziD51xllS?p=preview (as also explained in a previous comment) – Günter Zöchbauer Feb 23 '16 at 12:03
  • thank you, it solved my problem, is this behaviour documented somewhere? – kemsky Feb 23 '16 at 12:14
  • Can't find anything. I only remember seeing it mentioned in a discussion. – Günter Zöchbauer Feb 23 '16 at 12:16
  • 5
    Thanks for mentioning ` is only a projection - the elements are displayed at a different place is all, they are still "owned" by the component where they are added originally.` – Gangadhar Jannu May 16 '17 at 13:02