22
- June
2020
Posted By : Rahul
Blazor Data Binding in Depth – Part 2

In this post, we will cover up all remaining data binding related points left in our previous article blazor data binding in depth. We will discuss about two-way data binding between nested components, event handling with DOM events as well as custom events, EventCallBack and passing data from child component to parent component.

In our previous article, we discussed about one-way data binding and two-way data binding in a single component. Also we discussed about multiple forms of @bind attribute such as data formatting, two-way data binding with specific event and more. If you have not gone through part of this article, please check it Blazor Data Binding in Depth.

You can download demo project with examples explained from GitHub.

Event Handling

Blazor components provide event handling features. When an event is fired in blazor component, blazor calls StatusHasChanged internally. That means blazor re-renders the UI. If you are not aware with StatusHasChanged() method in blazor, check it here.

There are basically two type of events –

DOM Events – DOM events are the events that come by default with html DOM like onclick, onkeyup, onkeypress etc. When user interacts with them, those are triggered to perform some kind of specific operation.

User-defined Events – User-defined events also called custom events that are created by user itself for performing some kind of custom operation based on application needs.

Let’s understand first DOM events handling in blazor components with the help of an example –

DOM events handling

Any DOM event such as onclick, onkeypress etc. can work with HTML element inside blazor components. That means you can access any DOM event with HTML element in blazor. Syntax for accessing events with HTML in blazor would be following –

@on{EVENT} = “EVENT_HANDLER”

EVENT – it can be any DOM event.
EVENT_HANDLER – this is a method the executes when event triggers.

For example, if you want to perform any operation on clicking of a <button> element, then the @onclick attribute will be used and this attribute value is used as an event handler. In the following example, IncrementClick handler will be called when @onclick event will be fired.

<p>Counter: @counterValue</p>

<button @onclick="IncrementClick">Click Me</button>

@code {
    private int counterValue = 0;

    protected void IncrementClick()
    {
        counterValue++;
    }
}

Let’s see another example with html <checkbox> element. The method CheckBoxChanged will be called when checkbox will be checked or unchecked.

Subscribe to Alerts: 
<input type="checkbox" @onchange="CheckBoxChanged" />

<p>Is Subscription done? - @checkBoxValue</p>

@code {
    private bool checkBoxValue = false;

    protected void CheckBoxChanged()
    {
        checkBoxValue = !checkBoxValue;
    }
}

Event Handler as Lambda Expression

Events handlers can also be used as lambda expressions, so above both examples could be written as follows –

<h3>Blazor components event handling with example</h3>

<!-- button onclick event -->
<button @onclick="@(() => counterValue++;)">Click Me</button>
<p>Counter: @counterValue</p>

<!-- checkbox onchange event -->
Subscribe to Alerts: 
<input type="checkbox" @onchange="@(() => checkBoxValue = !checkBoxValue)" />
<p>Is Subscription done? - @checkBoxValue</p>

@code {
    private int counterValue = 0;
    private bool checkBoxValue = false;
}

In above code example, you can see both event handlers have been used as lambda expressions.

blazor data binding part -2 event handling

Asynchronous Event Handler

Event handlers can be asynchronous too and can return a Task. Asynchronous event handlers are used for performing any asynchronous operation on triggering an event. For example you want to retrieve data from server side API and display the data in blazor component. See the following example.

<button @onclick="GetRecords">Get Records</button>

@code {
    private List<string> names { get; set; } = new List<string>();

    protected async Task GetRecords()
    {
        //any asynchronous call like get data from API
        
        names = await employeeService.GetNames();
    }
}

Event Handler with Event Argument Types

Sometimes we need event data to do some specific operations. Event data means event type i.e. EventArgs that provides the data about the specific event passing as parameter of Event handler method when an event is triggered. There is no need to pass event type in the event handler as parameter until the event data is not required inside the handler method.

Let’s take an example and understand it . Suppose you need to perform any specific operation when user types something in the <input> box and hits enter. In this case you need event data passing as parameter of event handler executed on keypress event. Because you need to check what key is pressed. In the following example, I use @onkeypress event and prints each key pressed by user.

<h3>Event Handler with EventArgs Example</h3>

Enter any key: <input type="text" @onkeypress="KeyPressed" />
<br/>
@foreach(var s in PressedKeys)
{
    @s <br/>
}

@code {
    private List<string> PressedKeys { get; set; } = new List<string>();
    protected void KeyPressed(KeyboardEventArgs e)
    {
        PressedKeys.Add($"Key: {e.Key}, Code: {e.Code}");
    }
}
blazor data binding in depth - event handlers

Some common events and its types are described here.

EventEvent TypesBlazor Events
InputChangeEventArgsonchange, oninput
KeyboardKeyboardEventArgsonkeydown, onkeypress, onkeyup
MouseMouseEventArgsonmousedown, onmouseup, onmouseover etc.
Mouse WheelWheelEventArgsonwheel, onmousewheel

👉 Blazor supports lot of DOM events and its types. You can find all of them here in official blazor document.

Custom Events Handling

Sometimes we need to create our own custom events for doing some specific operations. For example, in our last article Blazor Data Binding in Depth – Part 1 we had covered that how to pass data from parent component to child component? But what, if you want to pass data from child component to parent component. This is where custom events are needed.

EventCallBack

An EventCallBack is a special type of delegate which is used in a common scenario with nested components to execute a parent component method when a child component event occurs. Also, we can say that for passing any data from child component to parent component when any event is occurred inside child component, blazor provides us a special type of delegate called EventCallBack.

Let’s take an example and understand its use. Suppose we have two components parentcounter and childcounter. Parent counter increases the value of counter and pass incremented value to child using [parameter] attribute. What, if you want to increase the same counter value from child component and pass that incremented value to parent as well.

ParentComponent.razor

<h3>Parent Component</h3>

<button @onclick="IncrementCountFromParent">Parent Incrementor</button>

<p>Counter Value inside Parent component: @counter</p>

<!-- Nested Child Component -->
<ChildCounter CounterValue="@counter" CounterValueChanged="CounterIncreased"></ChildCounter>

@code {
    private int counter;

    protected void IncrementCountFromParent()
    {
        counter++;
    }

    public Task CounterIncreased(int incrementedCounterValue)
    {
        counter = incrementedCounterValue;
        return Task.CompletedTask;
    }
}

ChildComponent.razor

<h3>Child Component</h3>

<button @onclick="IncrementCounterFromChild" >Child Incrementor</button>

<p>Counter Value inside Child component: @CounterValue</p>

@code {
    [Parameter]
    public int CounterValue { get; set; }

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

    protected async Task IncrementCounterFromChild()
    {
        CounterValue++;
        await CounterValueChanged.InvokeAsync(CounterValue);
    }
}

In above example, in child component a custom event is defined called CounterValueChanged and parent component assign a callback method to this child component’s custom event. When this custom event is triggered from child component using InvokeAsync method, callback method from parent component will be executed and get the incremented value of counter.

blazor data binding part -2 eventcallback

👉 StatusHasChanged() method is called automatically to re-render the UI when child event triggers.

blazor data binding in depth part-2 two-way binding between components

Using EventCallBack with @bind attribute

There is another form of using EventCallBack delegate without passing callback method from Parent component. This is a short syntax of what I explained in above example.

<!-- Parent Component -->
<ChildCounter @bind-CounterValue="@counter"></ChildCounter>

As you can see in above code, we did not provide callback method to child component’s EventCallBack delegate in parent component as we did in previous example. After running the application, still you can see the same output means both parent as well as child components can increase the counter values that gets updated in both components.

How does it work?

When we use @bind attribute with child component’s parameter while passing value from parent component (e.g. @bind-CounterValue=”[property]“), Blazor by default will look for an event in child component using the naming convention of {property}Changed meaning whatever property for example,  CounterValue decorated with [parameter] attribute in child component, is used with @bind attribute, same name event must be inside child component named CounterValueChanged.

Summary (Blazor Data Binding in Depth)

In this article, we have covered –

👉 Event handling in Blazor component.
👉 How DOM events and custom events are handled in Blazor components?
👉 How event handler methods can be used as lambda expressions?
👉 How event handler methods can be used asynchronously?
👉 What is EventCallBack?
👉 How to pass data from child component to parent component using EventCallBack<T>?

Thank you 🙏 for reading this article. Keep Reading, Keep Growing, Keep Sharing 😃


If you found this article helpful,

BMC logoBuy me a coffee


Follow Us For Latest Posts –

Leave a Reply