sw1337
sw1337

Reputation: 999

Blazor: binding a class to input elements directly

In a grocery list app, I have a parent component looping over grocery items, and a child component showing details for each grocery item using input elements (a checkbox and a text field). I've set up two-way binding directly to the GroceryItem members and it's working fine as far as updating the members with input data.

Where I have a problem is to notify the parent component to re-render itself. I know I have to invoke an EventCallBack when I detect a change, but I want to avoid duplicating my class members as local variables, just to be able to use the setter for detecting the change and invoke the EventCallBack. The other trick I found was to manually bind the data, but again this create duplication since I have to set up an event handler for each input element.

Is there a better way?

I wish there was a mechanism by which I could add more onchange event handlers to the input elements, in order to invoke EventCallBack... But because bind takes up the only slot available I can't.

// This is the child component

<li>
    <input type="checkbox" @bind=Item.Purchased />
    <input type="text" @bind=Item.Name />
</li>

@code
{
    [Parameter]
    public GroceryItem Item { get; set; }

    [Parameter]
    public EventCallback<GroceryItem> ItemChanged { get; set; }
}

Upvotes: 0

Views: 817

Answers (2)

Artak
Artak

Reputation: 2887

Being able to register an additional event handler for an event you've a binding for isn't supported yet: https://github.com/dotnet/aspnetcore/issues/14365

One way you can work around (I haven't tried this but I think this may work) may be to define helper properties in your component and bind directly to them instead. The below code demonstrates it for just one of these:

<li>
    <input type="text" @bind=Name />
</li>

@code
{
    [Parameter]
    public GroceryItem Item { get; set; }

    private string Name
    {
      get => this.Item.Name;
      set => this.Item.Name = value;
    }

    [Parameter]
    public EventCallback<GroceryItem> ItemChanged { get; set; }
}

If this doesn't work I'll remove it, so people don't get confused about a wrong answer. Just an attempt to help.

If this works, then you can fire your event in the setter of the helper property.

Upvotes: 0

Ali Borjian
Ali Borjian

Reputation: 1108

If you want to call a parent component method from a child one, you need to use EventCallback.
However there are a lot of ways to call a method in a child component from a parent component.
To find out more, see the Blazor LifeCycle and RenderTree.
parent component has a full control over its children but a child only calls the parents by callback.

Upvotes: 0

Related Questions