angulardart / angular

Fast and productive web framework provided by Dart
https://pub.dev/packages/angular
MIT License
1.83k stars 232 forks source link

`@ContentChildren(typeOrString, descendants: true)` doesn't work #195

Closed zoechi closed 7 years ago

zoechi commented 7 years ago

@ContentChildren() doesn't work when the elements were passed through 2 components

<grand-parent>
    <child></child>
    <child></child>
</grand-parent>

Where <grand-parent> looks like

<parent>
  <ng-content></ng-content>
</parent>

and <parent> like

<ng-content></ng-content>

I want to query the children from the ParentComponent

the children are displayed where they are expected, just

@ContentChildren(ChildComponent, descendants: true) QueryList<ChildComponent> children;

doesn't work (with or without descendants: true)

When I use ParentComponent like

<parent>
    <child></child>
    <child></child>
</parent>

The ContentChildren() query works fine.

I combined parent and child into one component and this work as well (with only one <ng-content> level) .

matanlurey commented 7 years ago

Is this a bug (i.e. it works in Angular TS right now) or a feature request?

zoechi commented 7 years ago

I thought it's what descendants: true is for. Is it not? I think I have tried it in Plunker a while ago. I'll try it again and post an update.

zoechi commented 7 years ago

https://plnkr.co/edit/QoZXSLR0U3gy7iD7Cxjn?p=preview

matanlurey commented 7 years ago

Sorry, look like this is not supported.

We'll keep this in mind for future versions, but no changes for now.

jiayihu commented 7 years ago

@matanlurey @zoechi any plan about this support or any other solution? Seems to me that is currently impossible to wrap any component which uses ng-content, for example wrapping AccordionComponent into MyAccordion which uses also ng-content to put content inside AccordionComponent.

zoechi commented 7 years ago

@jiayihu sounds like a different but probably related issue.

jiayihu commented 7 years ago

@zoechi I think it's the same issue. You can see MyAccordion as grand-parent and AccordionComponent (from a lib like ng-bootstrap) as parent. I'm trying to find a solution but haven't found any so far.

zoechi commented 7 years ago

@jiayihu It's one issue that transclusion doesn't work 2 levels deep, and I think it's a different issue when you can't query 2 levels transcluded content.

jiayihu commented 7 years ago

@zoechi Forgot to mention that in my case, AccordionComponent from ng-boootstrap is actually using @ContentChildren: https://github.com/ng-bootstrap/ng-bootstrap/blob/master/src/accordion/accordion.ts#L131 That makes it impossible for me to wrap it into my own component.

RockNHawk commented 7 years ago

@matanlurey Are there any plan for this issue?

adickenscheidt commented 7 years ago

Can we please reopen this issue? Seems very counterintuitive for me since the 'descendants' property is offered in the documentation but doesn't work.

This will be a problem every time you use the ContentChildren decorator and try to organize your code by wrapping definitions into a new component, which I suppose many users do.

leonsenft commented 7 years ago

It's one issue that transclusion doesn't work 2 levels deep

@zoechi Have you looked into ngProjectAs? See an example from this AngularTS issue. I tested that this works in AngularDart as well. Unless I'm misunderstanding what doesn't work, you should be able to transclude multiple levels using select and ngProjectAs. Hope this helps!

and I think it's a different issue when you can't query 2 levels transcluded content

Unfortunately it doesn't help with this issue.

zoechi commented 7 years ago

@leonsenft thanks a lot for the hint, I'll try it. Any idea why ngProjectAs is required?

leonsenft commented 7 years ago

@zoechi I just stumbled upon ngProjectAs in the source code yesterday while working on something else and looked it up out of curiosity. The only mention of it I can find is in the issue I linked and ones referencing it. It's not officially documented in either AngularDart or AngularTS yet.

It seems like it's necessary if you want to select projected content 2+ levels deep. In your example, <child> is projected into the <ng-content> in grand_parent.html. However, when this content is projected again into parent.html, the compiler projects it as a single <ng-content> instead of the individual <child> elements inside.

In order to project the content a second time as something other than <ng-content>, use ngProjectAs. This tells the compiler when projecting it a second time to treat it as if it matches ngProjectAs, allowing it to be slotted into an <ng-content> with a matching select value.

sam-s4s commented 7 years ago

So I stumbled upon this issue while having the following problem (below is an example to illustrate)...

- text is a text input
- form-group's template = '<ng-content></ng-content>'
- address's template = '<text></text>'

<form-group>
    <text></text>
    <address></address>
</form-group>

From within the form-group component, I want to get a list of ALL text components. Even the ones inside other components, and regardless of whether they're also inside ng-content templates.

Currently the following only will return the direct child text component belonging to the form-group, and it does not return the one inside the address component...

@ContentChildren(TextComponent, { descendants: true }) textComponentList: QueryList<TextComponent>;

{ descendants: true } has no effect on the outcome. But I would expect it to also return the text component inside the address component.

adickenscheidt commented 7 years ago

@sam-s4s Have you tried using ngProjectAs as others have described above? With this you should be able to query for the elements more than one level deep. However, you'll not be able to use the Type for your query if I'm not mistaken.

leonsenft commented 7 years ago

@adickenscheidt I believe the issue @sam-s4s is describing is related to querying through multiple levels of projection, whereas ngProjectAs is used for projecting content through multiple <ng-content> tags.

@zoechi pointed this distinction out earlier in the discussing:

It's one issue that transclusion doesn't work 2 levels deep, and I think it's a different issue when you can't query 2 levels transcluded content.

sam-s4s commented 7 years ago

Yes, @leonsenft is correct :) I want to query through multiple levels of projection.

Also, is it still considered projection when you're talking about a sub-component with a template? As in my example, the address component doesn't have an ng-content - it just literally has the component in its template.

pesimeao commented 6 years ago

@sam-s4s I believe this is related https://github.com/angular/angular/issues/12930#issuecomment-287845199

Any progress on this issue? I believe the query should work accross multiple projection levels

camsteffen commented 5 years ago

Shouldn't this issue at least be open?

holger-at-schottel-de commented 3 years ago

Please re-open this issue and fix it.

PavelTurk commented 2 years ago

Please, reopen this issue. So many people ask to reopen and fix this issue but there is still no answer. Then once again, please, reopen this issue and fix it.

sam-s4s commented 2 years ago

So I think this is the wrong place for this issue. This repo is for Angular Dart, and is in maintenance mode.

Perhaps we should create a new issue at angular/angular for this?

PavelTurk commented 2 years ago

@sam-s4s I agree with you. As I've found, there is already such issue. This is a link: https://github.com/angular/angular/issues/16299