Blazor provides two-way communication from JS to C# and C# to JS which is called Interop. The version upgrade to Blazor 0.5.0 changed the approach in interactions between cshtml and JS files. The newer version simplifies JS calling by avoiding pre-registration of JS function.
In this article, we would see how to call a JS method by passing multiple parameters from cshtml and parameterized call from JS to cshtml. The scenario that is used in this article has a Kendo AutoComplete to search book and populate information based on the selection.
An example of a call to JS from cshtml
Takeaways from the above example:
- JSRuntime.Current give environment to execute out-process JS.
- InvokeAsync is a function that would allow executing the JS function.
- The searchBook.Init is a JS function call, we would see it in details in the second section.
- InvokeAsync allows passing multiple parameters, in this case, we are are passing JS selector for searching of books.
- DotNetObjectRef is kind of a wrapper with callback instance provided to JS. If we want to call server with an associated instance to yourself, then we have to use this. In case of a static method call, we do not need this. It would allow maintaining an instance and provide communication from JS to the server, for the same reason this has to be disposed somewhere too once the task is completed.
Calling to cshtml from JS
App.ts
- The calls that are made on client shall have a global scope that is why SearchBook instance is set on the window on the last line.
- Init method has two parameters the first is element id/jQuery selector and the second one is a dotnet class instance wrapper through which we can communicate back to the server.
- OnSelect event of kendoAutoComplete callback is happening to the server by passing the value in SetBookId function. Here I am not using promises since I am not expecting any value from this.
The server code has to be tagged with a JsInvokable attribute. Here are codes for cshtml:
This was a part of Blazor demo application that I was trying to create but found this critical since there was not any resource related to same. Here is the full source code of demo application: https://github.com/viku85/BlazorDemo
In this article, we would see how to call a JS method by passing multiple parameters from cshtml and parameterized call from JS to cshtml. The scenario that is used in this article has a Kendo AutoComplete to search book and populate information based on the selection.
An example of a call to JS from cshtml
await JSRuntime.Current.InvokeAsync<string>(
"searchBook.Init", "#SearchTitle", new DotNetObjectRef(this));
Takeaways from the above example:
- JSRuntime.Current give environment to execute out-process JS.
- InvokeAsync is a function that would allow executing the JS function.
- The searchBook.Init is a JS function call, we would see it in details in the second section.
- InvokeAsync allows passing multiple parameters, in this case, we are are passing JS selector for searching of books.
- DotNetObjectRef is kind of a wrapper with callback instance provided to JS. If we want to call server with an associated instance to yourself, then we have to use this. In case of a static method call, we do not need this. It would allow maintaining an instance and provide communication from JS to the server, for the same reason this has to be disposed somewhere too once the task is completed.
Calling to cshtml from JS
App.ts
class SearchBook {
public Init = (selector, donetHelper) => {
this.InitAutoComplete(selector, donetHelper);
}
public InitAutoComplete(selector: string, donetHelper) {
$(selector).kendoAutoComplete({
dataTextField: "bookTitle",
dataValueField: "id",
filter: "startswith",
minLength: 1,
dataSource: {
serverFiltering: true,
transport: {
read: "api/book/",
}
},
select: (data) => {
donetHelper.invokeMethodAsync('SetBookIdAsync', data.dataItem.id);
}
});
}
}
(<any>window).searchBook = new SearchBook();
- The calls that are made on client shall have a global scope that is why SearchBook instance is set on the window on the last line.
- Init method has two parameters the first is element id/jQuery selector and the second one is a dotnet class instance wrapper through which we can communicate back to the server.
- OnSelect event of kendoAutoComplete callback is happening to the server by passing the value in SetBookId function. Here I am not using promises since I am not expecting any value from this.
The server code has to be tagged with a JsInvokable attribute. Here are codes for cshtml:
@page "/book/search"
@using BlazorDemo.Model.DataModel
@inject HttpClient client
@using Microsoft.JSInterop;
<div>
<input id="SearchTitle" />
<p>Type for selection of book.</p>
</div>
<hr />
@if (Book != null)
{
<div class="well well-lg">
<h6>Title: <b>@Book.BookTitle</b></h6>
<h6>ISBN: <b>@Book.ISBN</b></h6>
<h6>Publisher: <b>@Book.PublisherName</b></h6>
</div>
}
@functions{
Book Book = null;
[JSInvokable]
public async Task SetBookIdAsync(int bookId)
{
Book = await client.GetJsonAsync<Book>($"api/book/{bookId}");
StateHasChanged();
}
protected override async Task OnAfterRenderAsync()
{
await JSRuntime.Current.InvokeAsync<string>(
"searchBook.Init", "#SearchTitle", new DotNetObjectRef(this));
}
}
This was a part of Blazor demo application that I was trying to create but found this critical since there was not any resource related to same. Here is the full source code of demo application: https://github.com/viku85/BlazorDemo
Comments
Post a Comment