Reputation: 11673
New to Blazor, having trouble getting a CascadingParameter
to populate from my MainLayout.razor
:
@code
{
private Toasts Toasts { get; set; }
}
<Toasts @ref="@Toasts" />
<CascadingValue Value="Toasts">
@Body
</CascadingValue>
And Index.razor
page:
[CascadingParameter]
public Toasts Toasts { get; set; }
public async Task PackageChanged(string value)
{
Toasts.Something(value); //Toasts is null here
}
And finally Toasts.razor:
@code {
private string Message { get; set; }
public void Something(string message)
{
Message = message;
StateHasChanged();
}
}
@Message
This code below frustratingly works, but I'd like to cascade just the one component (<Toasts />
) instead of the whole layout:
<CascadingValue Value="@this">
<Toasts @ref="@Toasts" />
@Body
</CascadingValue>
And then index:
[CascadingParameter]
public MainLayout Layout { get; set; }
public async Task PackageChanged(string value)
{
Layout.Toasts.Something(value); //this behaves as expected
}
Upvotes: 3
Views: 8328
Reputation: 45596
This code is working for me
<div class="main">
<div class="top-row px-4">
<Toasts @ref="Toasts" />
</div>
@if (Toasts != null)
{
<CascadingValue Value="@Toasts">
@Body
</CascadingValue>
}
</div>
@code
{
protected Toasts Toasts;
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
StateHasChanged();
}
}
}
The following solution, in which we cascade a reference to MainLayout, and then retrieve a reference to the Toasts component, is a bit more effective than the one above, as it does not require the MainLayout to render a second time.
<div class="main">
<div class="top-row px-4">
<Toasts @ref="Toasts" />
</div>
<CascadingValue Value="this">
@Body
</CascadingValue>
</div>
@code
{
public Toasts Toasts { get; set; }
}
@page "/"
@code{
[CascadingParameter]
public MainLayout Layout { get; set; }
protected override void OnInitialized()
{
// Reference the Toasts component's methods and properties
// Note: You must not pass parameter values to the Toasts
// component from here. You'll get a warning, or perhaps
// an error.
Layout.Toasts.Something("Pass a message to the
Something method");
}
}
Upvotes: 4
Reputation: 1450
This statement in MainLayout.razor do not work
<Toasts @ref="@Toasts" />
But this statement works and cascading parameter in index.razor is not null
@code
{
private Toasts Toasts= new();
}
Seems that Blazor do not allow to pass element references as cascading parameter but only allows object and other variables. I do not have full context of your requirements, but you can try implementing Toasts as a service.
Upvotes: 1