analog
analog copied to clipboard
Support ng-content inside the astro-angular package
Which scope/s are relevant/related to the feature request?
astro-angular
Information
Content projection is done easily inside Angular itself using <ng-content />.
Anything added inside the opening and closing components tags would be rendered here.
For example:
<my-card variant="lg">
Hello World
</my-card>
This would render the my-card with any attributes given to the component. And additionally if the component has a ng-content slot defined it would render my Hello world text inside of here.
I would expect that in Astro the same behaviour would happen but i understand it does not. If we would support this we would get even more Angular goodies inside Astro.
Besides having normal slots, you can also have named slots. For example this template:
<h2>Multi-slot content projection</h2>
Default:
<ng-content></ng-content>
Question:
<ng-content select="[question]"></ng-content>
You would render the corresponding content of it using an attribute like this:
<app-zippy-multislot>
<p question>
Is content projection cool?
</p>
<p>Let's learn about content projection!</p>
</app-zippy-multislot>
This would probably be more tricky to support, but maybe this could also be tackled?
Describe any alternatives/workarounds you're currently using
Instead of ng-content you could make inputs for everything, but this will not give the same freedom and therefor will only work for simple components.
I would be willing to submit a PR to fix this issue
- [X] Yes
- [ ] No
(I have no idea where to start tho and it might be to hard for me)
@thebspin A good place to start might be here
https://github.com/analogjs/analog/blob/beta/packages/astro-angular/src/server.ts#L76-L82
There is an unused _children property on this function. See here where that same property (called slot) is being used.
It doesn't look like any of the Angular functions being called in the rest of renderStaticMarkup can accept children/slots but there is this method in @angular/core:
https://github.com/angular/angular/blob/e02bcf89cf77c3118c649a7db68e66a78f16155c/packages/core/src/render3/component.ts#L73
However this requires an EnvironmentInjector. I think these might be the pieces needed, but I'm not sure how to put them together
@seeplusplus
Thanks, today i had some time and tried this route (seems the most logical) but unfortunaly when calling the createComponent function i get an Angular error i have yet to solve.
NG0407: Angular was not able to inject a renderer (RendererFactory2). Likely this is due to a broken DI hierarchy. Make sure that any injector used to create this component has a correct parent.
I do pass the bootstrap.injector as an option and that should work but it doesn't..
EDIT: it's probably because bootstrap.injector is empty, where bootstrap is the result of the bootstrapApplication function that's already in place
Closing as a no-go for now
I don't quite understand how this isn't seen as essential behavior to support <ng-content> or even <ng-content select="">. Any existing Angular component library heavily relies on using <ng-content>, which is therefore currently unusable.