Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(core): correctly fallback ng-content with projectable nodes. #57480

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

Conversation

chintankavathia
Copy link
Contributor

@chintankavathia chintankavathia commented Aug 22, 2024

projectableNodes should allow to pass empty nodes to fallback to default ng-content for that placeholder without affecting rendering of remaining nodes.

Fixes #57471

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Currently default ng-content fallback fails when projectableNodes are passed as empty in between of nodes.
e.g for below component template

<ng-content>One Fallback</ng-content>
<ng-content>Two Fallback</ng-content>
<ng-content>Three Fallback</ng-content>

if the projectableNodes are passed like this [[customContentElement], [], [anotherContentElement]];
it will render

<customContentElement/>
<anotherContentElement/>

Issue Number: 57471

What is the new behavior?

It should render default fallback for empty nodes like below.

<customContentElement/>
Two Fallback
<anotherContentElement/>

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@pullapprove pullapprove bot requested a review from devversion August 22, 2024 05:58
@angular-robot angular-robot bot added the area: core Issues related to the framework runtime label Aug 22, 2024
@ngbot ngbot bot added this to the Backlog milestone Aug 22, 2024
@devversion devversion requested review from crisbeto and removed request for devversion August 22, 2024 07:02
@chintankavathia chintankavathia force-pushed the projectable-nodes-with-fallback branch from d7be1bc to fa8b2b3 Compare August 22, 2024 07:42
@devversion
Copy link
Member

devversion commented Aug 22, 2024

I might miss something from a quick glance. What would happen if someone wants to explicitly avoid the ng-content default and project zero nodes? Should null be used for explicitness to fall back

@chintankavathia
Copy link
Contributor Author

I might miss something from a quick glance. What would happen if someone wants to explicitly avoid the ng-content default and project zero nodes? Should null be used for explicitness to fall back

in that case they can pass document.createTextNode('')

@devversion
Copy link
Member

It does sound like this would be a breaking change though?

@chintankavathia
Copy link
Contributor Author

It does sound like this would be a breaking change though?

You are right 💯 . so now the question is should we do this as breaking change or do you prefer to change projectableNodes type to (Node[] | null)[].

@diesieben07
Copy link

It does sound like this would be a breaking change though?

I might be missing something, but right now null is not a valid entry in the nodes array. So if null is introduced as a way to say "do not project anything here" instead of "project zero nodes here", would that not be backwards compatible?

@devversion
Copy link
Member

I will defer to @crisbeto on how to treat this, as he is the expert on projection and its APIs.

@diesieben07 I think it wouldn't be a breaking change, if null is introduced as a way to say: "do not project anything, but use the default ng-content". That way this PR is basically an opt-in feature.

BREAKING CHANGE: Render default fallback with empty `projectableNodes`.

When passing an empty array to `projectableNodes` in the `createComponent` API, the default fallback content of the `ng-content` will be rendered if present. To prevent rendering the default content, pass `document.createTextNode('')` as a `projectableNode`.

For example:

```ts
// The first ng-content will render the default fallback content if present
createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });

// To prevent projecting the default fallback content:
createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

```

Fixes angular#57471
@chintankavathia chintankavathia force-pushed the projectable-nodes-with-fallback branch from fa8b2b3 to a232f94 Compare August 25, 2024 13:55
@angular-robot angular-robot bot added the detected: breaking change PR contains a commit with a breaking change label Aug 25, 2024
Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic makes sense, but will run a global presubmit just in case.

@diesieben07
Copy link

I just tried this out in current Angular and the behavior I described above (null means show the fallback) already exists in Angular today without any changes. The only problem is the type of projectableNodes, which does not allow null. The change introduced with this PR (as it is at the moment) alters behavior, because an empty array now means something different.

In my opinion the behavior should not be altered and instead the type of projectableNodes should be changed to correctly represent the current functionality: Array<Node[] | null>.

@devversion
Copy link
Member

devversion commented Aug 26, 2024

I'm agreeing with @diesieben07. I've explained that in: #57480 (comment). Right now this is a breaking change. I think @crisbeto might be verifying if that is actually breaking a lot? In either case, I'd personally prefer null.

@chintankavathia
Copy link
Contributor Author

In what situations might a user want to skip the projection and avoid falling back to the default value? Generally, when directly using a component in a template, falling back to the default is the more common approach. Therefore, I prefer to break from this pattern rather than introducing a null value.

@crisbeto
Copy link
Member

Passing TGP

@crisbeto crisbeto added action: merge The PR is ready for merge by the caretaker target: major This PR is targeted for the next major release labels Aug 27, 2024
@alxhub
Copy link
Member

alxhub commented Aug 27, 2024

This PR was merged into the repository by commit 7b1e5be.

The changes were merged into the following branches: main

@alxhub alxhub closed this in 7b1e5be Aug 27, 2024
@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 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime detected: breaking change PR contains a commit with a breaking change target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Default ng-content fallback doesn't work with custom elements or dynamic components using projectableNodes
5 participants