Author : MD TAREQ HASSAN | Updated : 2020/08/27

Data binding in blazor

One way binding to DOM

In one-way binding, we need to pass property or variable name along with “@” i.e. “@Title” (Title is either property or variable).

Counter.razor.cs

public class CounterBase : ComponentBase
{
	protected int Count { get; set; }
	
	protected EmployeeModel Employee { get; set; }

	// ... ... ...
}

Counter.razor

@page "/counter"
@inherits CounterBase

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

<p>First Name: @Employee.FirstName</p>

Two way binding to DOM

Counter.razor.cs

public class CounterBase : ComponentBase
{
	protected int Count { get; set; }

	// ... ... ...
}

Counter.razor

@page "/counter"
@inherits CounterBase

<input @bind="@Count" />
<input @bind="Count" />

Notes:

Binding between components

one-way binding

Syntax: <MyComponent MyProp="@..." />

two-way binding

Syntax:

<ChildComponent @bind-{Param}="@..." />  // child should have a property (event):  public EventCallback<T> {Param}Changed { get; set; }

`<ChildComponent @bind-{Param}="@..." @bind-Param:event="{Param}Changed" />`

<ChildComponent @bind-{Param}="{ParentComponentProp}" @bind-Param:event="{Param}Changed" />

It’s also possible to use a completely different name for the EventCallback property, for example, ParentsTitleUpdated. But in this case we would need to use the long form version of bind and specify the event name like so.

`<ChildComponent @bind-{Param}="@..." @bind-Param:event="EventHandlerName" />`

So, [Parameter] is used for:

One Way Binding Between Components

ParentComponent.razor.cs

public class ParentComponent : ComponentBase
{

	protected int Name { get; set; } = "Foo1";

	// ... ... ...
}

ParentComponent.razor


<h1>Parent name: @Name</h1>

<ChildComponent ParentName="@Name" />  <!-- Razor expression -->
<ChildComponent ParentName="Name" />   <!-- Property -->

ChildComponent.razor.cs

public class ChildComponent : ComponentBase
{
    [Parameter]
    protected int ParentName { get; set; }

    // ... ... ...
}

ChildComponent.razor

<h1>Parent name in child: @ParentName</h1>

Two Way Binding Between Components

ParentComponent.razor.cs

public class ParentComponent : ComponentBase
{

    protected int Name { get; set; } = "Foo1";
	
	// ... ... ...
}

ParentComponent.razor


<h1>Parent name: @Name</h1>

<ChildComponent @bind-ParentName="@Name" />

ChildComponent.razor.cs

public class ChildComponent : ComponentBase
{
    [Parameter]
    protected int ParentName { get; set; }
	
    [Parameter]
    public EventCallback<string> ParentNameChanged { get; set; }
	
    protected async Task UpdateParentName() {
	
        ParentName = "Foo3"
		
        await ParentNameChanged.InvokeAsync(ParentName);
    }

    // ... ... ...
}

ChildComponent.razor

<h1>Parent name in child: @ParentName</h1>

<button @onclick="@(async () => await UpdateParentName())">Update Parent Name</button>

Explanations:

Binding route path

[Parameter] annotation is used

IetmDetails.razor

@page "/items/{ItemId}"
@inherits ItemDetailsBase

<p>Item Name: @Item.Name</p>

IetmDetails.razor.cs

public class ItemDetailsBase : ComponentBase
{

    [Parameter]
	protected int ItemId { get; set; }
	
	public Item Item {get; set;}
	
	
	protected override Task OnInitializedAsysnc()
	{
		Item = Items.FirstOrDefault(item => item.Id == int.Parse(ItemId));
	}

	// ... ... ...
}

Format strings

<input @bind="StartDate" @bind:format="yyyy-MM-dd" />

See: https://docs.microsoft.com/en-us/aspnet/core/blazor/components/data-binding#format-strings