I am building a razor component for use in a Blazor client-side app. I am wondering how i can make the images used in the component dynamic, and set the images in the page code-block where i call the component.
Here is my Carousel.razor component
@inject IJSRuntime JsRuntime
@namespace BlazorFrontend.Components
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="1" ></li>
<li data-target="#carouselExampleIndicators" data-slide-to="2" ></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="pictures/foo.jpg" alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="pictures/bar.jpg" alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="pictures/foobar.jpg" alt="Third slide">
</div>
</div>
<a class="carousel-control-prev" role="button" id="carouselExampleIndicators-prev" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" id="carouselExampleIndicators-next" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
@code{
protected override async Task OnInitializedAsync()
{
foreach (System.Collections.DictionaryEntry de in Environment.GetEnvironmentVariables())
{
System.Console.WriteLine("ENVVAR: key=" + de.Key + " value=" + de.Value);
System.Console.WriteLine(Environment.GetEnvironmentVariable("ASSETS"));
}
}
private string AssetsEndpoint = Environment.GetEnvironmentVariable("ASSETS");
bool firstRender = true;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JsRuntime.InvokeAsync<object>("initializeCarousel");
firstRender = false;
}
}
}
Ideally, i would have liked to do something like this:
<img class="d-block w-100" src=@slide1 alt="First slide">
code{
string slide1;
}
and in the code block of the page i am using the component in:
<Carousel></Carousel>
code{
slide1 = "pictures/foo.jpg"
}
for example, but of course, that isn't going to work. What is the right/Blazor way of doing this?
BlazorStrap basically does this already, and their Carousels sample page also shows a fairly Blazor-esque way of doing it. From the first example:
<BSCarousel NumberOfItems="@items.Count">
<BSCarouselIndicators NumberOfItems="@items.Count">
<div class="carousel-inner">
@for (int i = 0; i <<> items.Count; i++)
{
<BSCarouselItem src="@items[i].Source" alt="@items[i].Alt">
}
</div>
<BSCarouselControl CarouselDirection="CarouselDirection.Previous" NumberOfItems="@items.Count">
<BSCarouselControl CarouselDirection="CarouselDirection.Next" NumberOfItems="@items.Count">
</BSCarousel>
Let's simplify that a little further first:
<BSCarousel NumberOfItems="@items.Count">
<div class="carousel-inner">
@for (int i = 0; i <<> items.Count; i++)
{
<BSCarouselItem src="@items[i].Source" alt="@items[i].Alt">
}
</div>
</BSCarousel>
The key aspects to note here:
BSCarousel
that semantically acts as the container, and can also interact with its child componentsBSCarouselItem
for each item added. This approach makes you fairly flexible and might be what you were asking. More tiles in the carousel? Just add another item. The parent BSCarousel
component, then, needs to deal with arranging them.@for
and @items.Count
is used to easily intersperse C# where needed, but really, C# is used here more as a template language@code { }
block isn't needed for this at all (note, though, that everything outside that block eventually gets transformed into C# anyway)I'm guessing your main question was: how do I put multiple items in a component? By making another component that handles a single item. :-)