By default, Blazor templates generate view logic code inside the Razor template using @functions
.
@page "/"
<!-- View (HTML) -->
@functions {
// Logic (C#)
}
There are many ways to separate view and logic which we will discuss here in this article.
One way of separating view and logic is to create a base class.
Let's have a look at an example which contains the view and view logic in single file.
@page "/jsinterop"
@using BlazorApplication.Pages
@using Microsoft.JSInterop
<h1>JavaScript Interop Demo</h1>
<hr />
<button class="btn btn-primary" onclick="@CallJSMethod">Call JS Method</button>
<button class="btn btn-primary" onclick="@CallCSMethod">Call C# Method</button>
<br />
<br />
<p id="demop">JavaScript function called from C#</p>
<br />
<p>@message</p>
@functions {
protected static string message { get; set; }
protected void CallCSMethod()
{
JSRuntime.Current.InvokeAsync<bool>("CSMethod");
}
protected void CallJSMethod()
{
JSRuntime.Current.InvokeAsync<bool>("JSMethod");
}
[JSInvokable]
public static void CSCallBackMethod()
{
message = "C# function called from JavaScript ";
}
}
Now, to isolate the view from view logic, let's move the C# code to the base class by creating a new Blazor component class and move all the C# code which is defined inside @functions
.
using Microsoft.JSInterop;
using Microsoft.AspNetCore.Blazor.Components;
namespace BlazorApplication.Pages
{
public class JSDemoModel : BlazorComponent
{
protected static string message { get; set; }
protected void CallCSMethod()
{
JSRuntime.Current.InvokeAsync<bool>("CSMethod");
}
protected void CallJSMethod()
{
JSRuntime.Current.InvokeAsync<bool>("JSMethod");
}
[JSInvokable]
public static void CSCallBackMethod()
{
message = "C# function called from JavaScript ";
}
}
}
The @inherits
directive can be used to provide Blazor with a code-behind experience that separates view markup from view logic code.
@page "/jsinterop"
@using BlazorApplication.Pages
@using Microsoft.JSInterop
@inherits JSDemoModel
<h1>JavaScript Interop Demo</h1>
<hr />
<button class="btn btn-primary" onclick="@CallJSMethod">Call JS Method</button>
<button class="btn btn-primary" onclick="@CallCSMethod">Call C# Method</button>
<br />
<br />
<p id="demop">JavaScript function called from C#</p>
<br />
<p>@message</p>
Blazor supports Dependency Injection, and it is one of the technique to isolate logic that is independent of the view, e.g., core business logic, data access logic, etc. Read more about Dependency Injection in Blazor.
Currently, Blazor does not support partial classes for its components (issue on GitHub). Therefore, you cannot just create a separate file and use the same class name as the component.