I have a razor page which depends on its parent's class and a second child which has its own class and receive data from its parent, my issue is on the second call to the api, the data is not being passed to the second child, the second child is not being render when its parent changes its data but it works on the first render and data is being passed.
Parent.razor
@inherits ParentBase;
<FirstChild/>
<SecondChild data="@data"/>
FirstChild.razor
@inherits ParentBase;
// call its parent method
<span @onclick='(() => callApi())'/>
ParentBase.cs
public class ParentBase : ComponentBase
{
public Data data { get; set; }
protected override async Task OnInitializedAsync()
{
data = await Services.GetData();
}
// call from a child
public void callApi
{
data = await Services.GetData();
}
}
SecondChild.razor
<Table data="@data"/>
SecondChildBase.cs
public class SecondChildBase : ComponentBase
{
[Parameter]
public Data data { get; set; }
protected override void OnParametersSet()
{
// this is not getting called
StateHasChanged();
Console.WriteLine(data);
}
}
Child component to parent component communication Child component (DisplayEmployee Component) should notify the parent component (EmployeeList Component) that a record is deleted so the parent component can remove the respective employee card from the list of employees. For this the child component exposes an event.
By using Blazor route parameters, you can pass values from one page to another page. Use NavigationManager to pass a value and route the parameter to another page. Follow this example to achieve passing values from one page to another. Get the passed Page1 parameter value in Page2.
To use two-way binding on a parameter simply prefix the HTML attribute with the text @bind- . This tells Blazor it should not only push changes to the component, but should also observe the component for any changes and update its own state accordingly.
Just because Parent.razor
and FirstChild.razor
inherits from the same class, it doesn't mean that the data of both classes (public Data data { get; set; }
) will have the same value when changed.
When you call callApi
in the FirstChild
, it will change it's own data
, if you want to change the parent's data
, you need to pass a parameter to FirstChild
which will be a function to call when the span
is clicked and that will call the Parent
's callApi
.
FirstChild.razor
<span @onclick="OnClick">Call Parent function</span>
@code
{
// Call this EventCallback when the span is clicked
[Parameter]
public EventCallback OnClick { get; set; }
}
Parent.razor
@inherits ParentBase;
@* Passing OnClick Parameter to call callApi*@
<FirstChild OnClick="@callApi" />
<SecondChild data="@data" />
I think you can try data-binding instead of CascadingParameter.
Documentation is here: https://docs.microsoft.com/en-us/aspnet/core/blazor/data-binding?view=aspnetcore-3.1
particularly on the two topics below:
Example: Parent Component
<PasswordField @bind-Password="password" />
@code {
private string password;
}
Example: Child Component
<input @oninput="OnPasswordChanged"
required
type="@(showPassword ? "text" : "password")"
value="@Password" />
@code {
private bool showPassword;
private string password;
private string validationMessage;
[Parameter]
public string Password
{
get { return password ?? string.Empty; }
set
{
if (password != value)
{
if (value.Contains(' '))
{
validationMessage = "Spaces not allowed!";
}
else
{
password = value;
validationMessage = string.Empty;
}
}
}
}
[Parameter]
public EventCallback<string> PasswordChanged { get; set; }
private Task OnPasswordChanged(ChangeEventArgs e)
{
Password = e.Value.ToString();
return PasswordChanged.InvokeAsync(Password);
}
}
Your child component needs to supply a {Password}Changed where {} is your parameter. This way, when child updates, parents are also updated (as well as all other bind parameters)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With