1
votes
<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="@IncrementCount">Click me</button>

@code {

[Parameter]
public string IncrementAmount
{
    set
    {
        currentCount = Convert.ToInt32(value);
    }
}

public int currentCount { get; set; }

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

async  Task IncrementCount()
{
    if (OnClick.HasDelegate)
    {
        currentCount=currentCount+1;

        await OnClick.InvokeAsync(DateTime.Now.ToString());//<-commenting this line updates currentCount 
    }
}
}

Why the currentCount is not getting updated when I click the button in the child component ? The currentCount is getting updated when I comment the OnClick.InvokeAsync line. The OnClick.InvokeAsync is sending the value back to parent withou any problem. (Actually I want to send the currentCount to parent, and since the currentCount not updating I'm sending a dummy datetime value back to parent).

I followed this example: Blazor send input text back to parent component

1

1 Answers

1
votes

Note that the Counter component is missing the @page directive as it is a child component.

Note that the Counter component define two parameter properties that are set in the parent component (Index). The first is named Amount and the second is called AmountChanged. This pair are designed so by convention: name of a property that will contain a value passed from the parent component, and EventCallback 'delegate' to call back and update the a parent's property. This is how we use two-way data binding between the two components (Parent and it's child). And this is how we declare the binding in the parent component: <Counter @bind-Amount="Amount" />

If, for instance, you change Amount to Count like this:

<Counter @bind-Count="Amount" />

The pair parameter properties in the Counter component should be named Count and CountChanged respectively.

The most important thing to realize is that this is how we create a two-way data-binding between Components.

Counter.razor

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="@IncrementCount">Click me</button>

@code {


[Parameter]
public int Amount { get; set; }
[Parameter] public EventCallback<int> AmountChanged { get; set; }


private int currentCount { get; set; }

protected override void OnInitialized()
{
    currentCount = Amount;
}


async Task IncrementCount()
{
    currentCount = currentCount + 1;

    if (AmountChanged.HasDelegate)
    {
        await AmountChanged.InvokeAsync(currentCount);
    }
}
}

Index.razor

@page "/"


<p>Amount in parentcomponent: @Amount.ToString()</p>

<Counter @bind-Amount="Amount" />

@code{
   private int Amount { get; set; } = 120;

}

Note: You don't have to define your values as string. You can, actually you should define amount as an int, and let the system take care of converting them.