Repository navigation
Description
I'm submitting a ... (check one with "x")
[ ] bug report => search github for a similar issue or PR before submitting
[x] 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
When you add something inside a ng-content tag you get an error message: element cannot have content.
Expected behavior
Should render the html inside the ng-content tag as a default if no content was given.
Minimal reproduction of the problem with instructions
Create a component that uses ng-content somewhere. Put some html inside, that should be rendered when nothing else is 'injected' there from outside. Then use the component somewhere else.
What is the motivation / use case for changing the behavior?
In some cases you need a default behavior that can be replaced. In my case its an app header that shows the logo. When you navigate to a sub-page the logo will be replaced by a back button. It feels strange to add something like an input property to hide or show the logo. Some default content for ng content placeholders would feel much more intuitive.
Please tell us about your environment:
Win10, Angular CLI beta 18, VS Code
- Angular version: 2.1.0
2.1.0 - Browser:
All - Language:
TS - Node (for AoT issues):
node --version=
Activity
mbeckenbach commentedon Oct 25, 2016
If i remember correctly thats the way multi slot transclusion works in ng 1
webmutation commentedon Jan 12, 2017
Is there any other way to have a fallback-content for the slot? I found a workaround but its quite ugly
DzmitryShylovich commentedon Jan 12, 2017
not yet
emilio-martinez commentedon Apr 25, 2017
I don't know if adding something inside
ng-contentis really the best approach for this, but I agree that a fallback value would be desirable. Perhaps it could interop withngIf Else Then?DrewLandgrave commentedon May 24, 2017
AndrinGautschi commentedon Aug 5, 2017
Anything new on this feature request?
acaua commentedon Sep 15, 2017
@webmutation , theres a slight mistake in your solution: you should test if
"ref.children.length == 0", not if"ref.childNodes.length == 0"It should be like this:
webmutation commentedon Sep 15, 2017
@acaua Actually that is not my code, but I agree node.children should be used and not node.childNodes, not that it is a mistake but falsely assumes that child nodes are of type Element. Even though it would be reasonable to assume that whatever is projected in ng-content would be of type Element, it can create issues, therefore the proper API should be used, and since node.children is supported for IE9+ cross browser support also is not an issue.
If we look at the polyfill for node.children we see the use of childNodes but it is filtered by node.nodeType === 1 (Where nodeType ===1 represents An Element node such as < p >or < div > ), so node.children should always work even when it needs to be polyfilled.
@mbeckenbach You are correct that is the way it works in ng1, therefore it would be nice to keep it consistent, unless there is a good reason to make it different.
Still hopping the ng1 behavior as suggested by OP gets added, since it was straightforward to use.
didii commentedon Oct 6, 2017
Keep in mind that both
childrenandchildNodeswill have different behavior depending on how you use them. See the examples below to decide which workaround you want to currently use.node.childrenonly works when another element is added. Not if only text is present.Example:
where
default-componenthas the template as @acaua mentions:This will result into
This is not the case when you use
childNodes. In that case, the opposite happens if the tag has any whitespace or comment.Example:
or
or
with as template
will all result into nothing that is displayed.
EDIT
Using
childNodeswe can however check it with the following function:This will ignore nodes that are only whitespace and are comments (nodeType 8).
jack-bliss commentedon Jan 18, 2018
being able to determine wether or not ng-content exists seems very important, and having an option that works with unviersal would be very nice.
benneq commentedon Mar 17, 2018
I have a similar requirement:
<h1><ng-content select="[title]"></ng-content></h1>I want to completely remove the
<h1>if there's no content set.Though I need something like this:
<h1 *ngIf="titleRef"><ng-content select="[title]" #titleRef></ng-content></h1>46 remaining items
Den-dp commentedon Sep 14, 2023
I was surprised that this doesn't work the same way as
NgTranscludewith a fallback content (angular.js)vneogi199 commentedon Nov 27, 2023
Can we have something like the default placeholder for
ng-content, similar to defer placeholderLPCmedia commentedon Mar 9, 2024
The design choice of having a "default behavior" that needs to be overridden in some cases seems like misguided inheritance. When a component has an input that basically is an if/else its likely 2 components or if absolutely needed conditional content projection. This means you have to bind this input for all sub-routes as well...
On the other hand: its unclear why ng-content wouldn't have the same behavior as a
<slot>in a standard web-component.feat(core): add support for fallback content in ng-content
feat(core): add support for fallback content in ng-content (angular#5…
nelson6e65 commentedon Apr 19, 2024
Only for Angular 18? 👀
angular-automatic-lock-bot commentedon May 20, 2024
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.