Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use ContentChildren with ngForTemplate #12094

Closed
colinkahn opened this issue Oct 5, 2016 · 5 comments
Closed

Unable to use ContentChildren with ngForTemplate #12094

colinkahn opened this issue Oct 5, 2016 · 5 comments
Labels
area: core Issues related to the framework runtime feature Issue that requests a new feature freq2: medium

Comments

@colinkahn
Copy link

colinkahn commented Oct 5, 2016

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
Getting directives with @ContentChildren does not work when the directives were created using ngForTemplate.

Expected behavior
Directives inside repeated templates using ngForTemplate should be picked up by @ContentChildren like they would if you were using ng-content.

Minimal reproduction of the problem with instructions
https://plnkr.co/edit/pt3fgjvL7yREdHKWl8IZ?p=preview

Check src/app.ts. You'll see that the Marker directive is being repeated by the template passed to Repeater, but Repeater cannot use @ContentChildren to query for Markers.

What is the motivation / use case for changing the behavior?
In general, this seems like it should work. My specific use case is making a pair of components, each that use ngForTemplate with one used inside the others template. Together they allow filtering of a collection whose items have sub-items. One feature is that if all items have been filtered out (IE, no matching results) a message should be shown. I would assume the way to do this would be to query for items from the parent and subscribe to changes.

Please tell us about your environment:
Reproducible in Plunker.

  • Angular version: 2.0.X
    2.0.1
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
    Tested in Chrome
  • Language: TypeScript 2
  • Node (for AoT issues): node --version =
@pkozlowski-opensource
Copy link
Member

If you want to observe changes to directives rolled out by ngFor in your example, you would like to query for ViewChildren and not ContentChildren. In your plunker content is:

<template let-n>
    <marker>{{n}}</marker>
  </template>

while view:

<h2>Found {{markers?.length}} Marker Content Children</h2>
<template
  ngFor
  [ngForOf]="items"
  [ngForTemplate]="tmpl"></template>

@colinkahn
Copy link
Author

colinkahn commented Oct 5, 2016

@pkozlowski-opensource I suspected that, but tried that as well (see updated plunker: https://plnkr.co/edit/pt3fgjvL7yREdHKWl8IZ?p=preview).

If this is an issue with ViewChildren I'll update the issue to reflect that.

Edit:

This example is closer to my actual use-case: https://plnkr.co/edit/gmrBU9kRbQpATtySV6xh?p=preview
Would this also be the same, where I'd have to consider NestedRepeater and Marker to actually be part of the view of Repeater since they're being unrolled by ngFor?

@chuckjaz chuckjaz added the area: core Issues related to the framework runtime label Oct 5, 2016
@tbosch tbosch added feature Issue that requests a new feature severity1: confusing freq2: medium labels Oct 6, 2016
@timblakely
Copy link

timblakely commented Oct 12, 2016

I think I ran into this while exploring using ViewChildren/ContentChildren within custom structural directives. It appears ViewChildren and ContentChildren can't see into views created by createEmbeddedView.

Plunker here. Parent can't see a grandchild in either ViewChildren or ContentChildren. And a directive on the Child cannot see anything except a TemplateRef (see console logs).

tbosch added a commit to tbosch/angular that referenced this issue Nov 4, 2016
…t a different place

Previously, if a `TemplateRef` was created in a `ViewContainerRef`
at a different place, the content was not query able at all.

With this change, the content of the template can be queried
as if it was stamped out at the declaration place of the template.

E.g. in the following example, the `QueryList<ChildCmp>` will
be filled once the button is clicked.

```
@component({
  selector: ‘my-comp’,
  template: ‘<button #vc (click)=“createView()”></button>’
})
class MyComp {
  @ContentChildren(ChildCmp)
  children: QueryList<ChildCmp>;

  @ContentChildren(TemplateRef)
  template: TemplateRef;

  @ViewChild(‘vc’, {read: ViewContainerRef})
  vc: ViewContainerRef;

  createView() {
    this.vc.createEmbeddedView(this.template);
  }
}

@component({
  template: `
<my-comp>
  <template><child-cmp></child-cmp></template>
</my-comp>
`
})
class App {}
```

Closes angular#12283
Closes angular#12094
tbosch added a commit to tbosch/angular that referenced this issue Nov 4, 2016
…t a different place

Previously, if a `TemplateRef` was created in a `ViewContainerRef`
at a different place, the content was not query able at all.

With this change, the content of the template can be queried
as if it was stamped out at the declaration place of the template.

E.g. in the following example, the `QueryList<ChildCmp>` will
be filled once the button is clicked.

```
@component({
  selector: ‘my-comp’,
  template: ‘<button #vc (click)=“createView()”></button>’
})
class MyComp {
  @ContentChildren(ChildCmp)
  children: QueryList<ChildCmp>;

  @ContentChildren(TemplateRef)
  template: TemplateRef;

  @ViewChild(‘vc’, {read: ViewContainerRef})
  vc: ViewContainerRef;

  createView() {
    this.vc.createEmbeddedView(this.template);
  }
}

@component({
  template: `
<my-comp>
  <template><child-cmp></child-cmp></template>
</my-comp>
`
})
class App {}
```

Closes angular#12283
Closes angular#12094
tbosch added a commit to tbosch/angular that referenced this issue Nov 4, 2016
…t a different place

Previously, if a `TemplateRef` was created in a `ViewContainerRef`
at a different place, the content was not query able at all.

With this change, the content of the template can be queried
as if it was stamped out at the declaration place of the template.

E.g. in the following example, the `QueryList<ChildCmp>` will
be filled once the button is clicked.

```
@component({
  selector: ‘my-comp’,
  template: ‘<button #vc (click)=“createView()”></button>’
})
class MyComp {
  @ContentChildren(ChildCmp)
  children: QueryList<ChildCmp>;

  @ContentChildren(TemplateRef)
  template: TemplateRef;

  @ViewChild(‘vc’, {read: ViewContainerRef})
  vc: ViewContainerRef;

  createView() {
    this.vc.createEmbeddedView(this.template);
  }
}

@component({
  template: `
<my-comp>
  <template><child-cmp></child-cmp></template>
</my-comp>
`
})
class App {}
```

Closes angular#12283
Closes angular#12094
@Dunos
Copy link

Dunos commented Dec 10, 2018

So, there is still no way to use "ContentChildren" with views created using "createEmbeddedView"? @timblakely

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime feature Issue that requests a new feature freq2: medium
Projects
None yet
Development

No branches or pull requests

6 participants