0
votes

I am hoping that someone can help me. I am trying to learn Blazor and I am creating an example site to create a shopping list. I am having issues updating the list items as I am unable to pass the items back from the Child Component to the parent component to then pass to the API call. From the update button I can hit the UpdateItem method but I am not sure how to pass the bound items from the three inputs.

<ListTemplate Loader="@GetShopping" ListGroupClass="orders-list">
    <Loading>Loading...</Loading>
    <Empty>Empty.......</Empty>
    <Item Context="item">
        <input @bind="item.Id" />
        <input type="checkbox" @bind="item.IsDone" />
        <input @bind="item.Item" />
        <button @onclick="UpdateItem">Update</button>
    </Item>
    <AddNew>
        <input placeholder="Something todo" @bind="newToDo" />
        <button @onclick="AddTodo">Add Todo</button>
    </AddNew>
</ListTemplate>

ListTemplate class @typeparam TItem

@if (items == null)
{
    @Loading 
}
else if (!items.Any())
{
    @Empty 
}
else
{
    <div class="list-group @ListGroupClass">
        @foreach (var item in items)
        {
            <div class="list-group-item">
                @Item(item) 
            </div>
        }
        @AddNew
    </div>}

@code 
{ 
    IEnumerable<TItem> items;

    [Parameter] public Func<Task<IEnumerable<TItem>>> Loader { get; set; }
    [Parameter] public RenderFragment Loading { get; set; }
    [Parameter] public RenderFragment Empty { get; set; }
    [Parameter] public RenderFragment AddNew { get; set; }
    [Parameter] public RenderFragment<TItem> Item { get; set; }
    [Parameter] public string ListGroupClass { get; set; }

    protected override async Task OnParametersSetAsync()
    {
        items = await Loader();
    }
}
2
Welcome...Please, make sure you read this: stackoverflow.com/help/someone-answersenet

2 Answers

0
votes

I'd suggest using a state class to handle the data and events, and make it responsible for the interactions with the API and the UI.

The state class handles all changes made from the UI and does not allow direct manipulation of entries, so it controls the state and can notify any consumers (e.g. the UI) about changes.

A good example of this approach is the Blazor FlightFinder sample app:

see AppState.cs

This is a simple state container that the UI classes inject. Components that need to know when the state changes can handle the OnChange event that this class uses.

0
votes

Step 1 You should prepare an eventcallback property in child component.

In ChildComponent:

[Parameter]
public EventCallback<T> OnClick { get; set; }

Step 2 You should create a method, which you can trigger to bind ChildComponent's OnClick property

In ParentComponent:

<ChildComponent Onclick="GetChildComponent"></ChildComponent>

@code { 
 public void GetChildComponent(ChildComponent childComponent)
 {
  ...
 }
}

Step 3 Now, all need you is to call binded method in ChildComponent

In ChildComponent:

<ChildComponent @onclick="(()=>OnClick.InvokeAsync(this))></ChildComponent>

Thus, you can reach property of child component what you want.

With This way you can trigger any method belong to parent. If you want to refresh parent you can create a method that includes StateHasChanged() and then bind.

Edit: I used T (typeparam) to get object as a return type, If you just want to get string value, you can change with string