I have searched in many places and so far I have not seen anything similar to what I have been thinking.
Let's say I want to create a reusable container component, like a card, form or a modal, and save that as a ViewComponent. How would I add new view components inside of the "body" of that main ViewComponent in a way that would make it maximally reusable?
The syntax here is just to demonstrate the idea of course, but for an exemplification, something like this:
<vc:parent var1="x" var2="y">
<vc:child var3="a" var4="b"></vc:child>
<vc:child var3="c" var4="d"></vc:child>
</vc:parent>
Is anything like this possible?
Not necessarily using ViewComponents, maybe partial views, as long as the primary goal of reusing the containers of other reusable elements is achieved.
I have looked into helpers but they are no longer available in Core.
Thank you very much!
So I figured out how to do it.
I used part of this tutorial about helpers: Templates With Razor
And modified it so it works with ViewComponents.
So to get it working, in a minimal example, create a ViewComponent class as such:
[ViewComponent(Name = "Test")]
public class VCTest : ViewComponent
{
public IViewComponentResult Invoke(Func<dynamic, object> Content)
{
return View(Content);
}
}
Create the actual template that you want, in a cshtml file like this:
@model Func<dynamic, object>
<div id="SomeTemplateTest">
@Model(null)
</div>
In this very simple case I just used the Func as model since there is only one parameter, but for more parameters you'd just have to call @Model.funname(null) instead of just @Model(null). No big deal.
when calling this component from your view, create your child elements beforehand like so:
@{Func<dynamic, object> children=
@<div>
<vc:child var1="a" var2="b"></vc:child>
<vc:child var1="c" var2="d"></vc:child>
<vc:child var1="e" var2="f"></vc:child>
</div>;}
The div is there only to encapsulate all the elements. I haven't found a way around that but it has no major implications.
Then call the parent ViewComponent tag passing on the parameters accordingly:
<vc:test content="children"></vc:form-test>
And that's it, worked perfectly. It is unfortunate that I could not find a more seamless way. But this does the job.
If anyone knows of a better alternative I'd love to know more.