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

Nested ng-content with selector doesn't get content #21550

Closed
bgotink opened this issue Jan 16, 2018 · 4 comments
Closed

Nested ng-content with selector doesn't get content #21550

bgotink opened this issue Jan 16, 2018 · 4 comments

Comments

@bgotink
Copy link

bgotink commented Jan 16, 2018

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

I have two components:

@Component({
  selector: 'my-inner',
  template: '<ng-content select="input"></ng-content>'
})
export class InnerComponent {}

@Component({
  selector: 'my-outer',
  template: `
    <my-inner>
      <ng-content select="input"></ng-content>
    </my-inner>
  `
})
export class OuterComponent {}

When the outer component is used with content, the content doesn't project, i.e. what I write is

<my-outer>
  <input placeholder="foo">
</my-outer>

which results in the following DOM:

<my-outer>
  <my-inner>
    <!-- no input here -->
  </my-inner>
</my-outer>

If we modify the <ng-content select="input"> in the InnerComponent to <ng-content select="input, ng-content">, it does output the correct DOM:

<my-outer>
  <my-inner>
    <input placeholder="foo">
  </my-inner>
</my-outer>

however we lose the fact that we only want input elements so this doesn't work when projecting multiple elements to different ng-contents.

Expected behavior

It should result in the correct DOM without workaround.

Minimal reproduction of the problem with instructions

http://plnkr.co/edit/GKaUMGTpI2K8BukQI6co?p=preview

What is the motivation / use case for changing the behavior?

I'm building a library of complex input components (e.g. input masks …) and I want the consumer of the library to provide the actual <input> element so they can control the placeholder, tabindex and aria attributes. Right now run into this because the date input in my library uses the input mask internally:

<!-- input mask template -->
<div class="placeholder">{{ placeholder }}</div>
<ng-content select="input"></ng-content>

<!-- date input template -->
<my-input-mask mask="../../....">
  <ng-content select="input"></ng-content>
</my-input-mask>

I can use the workaround for now, until I run into a component that needs multiple content projections.

Environment


Angular version: 5.2.0


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

@alexzuza
Copy link
Contributor

alexzuza commented Jan 16, 2018

It should result in the correct DOM without workaround.

Where did you find that it should work this way?
For me it works as it was designed.
So at least it's a feature request

@vicb
Copy link
Contributor

vicb commented Jan 16, 2018

As @alexzuza mentioned above, it works as designed and you also get it right in your plunker: what you want to re-project is the <ng-content>.

That being said, your use case is legit and there is a little known Angular construct for that: the ngProjectAs attribute which defines how the ng-content would be selected:

@Component({
  selector: 'my-wrapper-component',
  template: `
  <my-component>
    <ng-content select="input" ngProjectAs="input"></ng-content>
  </my-component>
  `
})
export class MyWrapperComponent {
}

@vicb vicb closed this as completed Jan 16, 2018
@bgotink
Copy link
Author

bgotink commented Jan 17, 2018

@alexzuza Based on how nested content projection works in ShadowDOM v0 (plunker, chrome only). ShadowDOM v0 is, afaik, what Angular's content projection and emulated style encapsulation are modeled to look like so this deviation from the ShadowDOM behaviour is unexpected.

@vicb Thanks for the info!

@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 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants