ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互调
Blazor WebAssembly可以在瀏覽器上跑C#代碼,但是很多時候顯然還是需要跟JavaScript打交道。比如操作dom,當然跟angular、vue一樣不提倡直接操作dom;比如瀏覽器的后退導航。反之JavaScript也有可能需要調用C#代碼來實現一些功能,畢竟客戶的需求是千變萬化的,有的時候只能通過一些hack的手段來實現。
.NET調用JavaScript函數
使用JSRuntime.InvokeVoidAsync調用無返回值的JavaScript函數
顯然我們的.NET類庫里不會有JavaScript內置的alert方法來顯示提示,這里演示下如何調用JavaScript的alert方法:
<h3>.net call javascript</h3> <button @onclick="CallJs">Call alert </button> @inject IJSRuntime jsRuntime @code {private void CallJs(){jsRuntime.InvokeVoidAsync("alert", "this message from .net runtime .");} }使用JSRuntime.InvokeVoidAsync調用具有返回值的JavaScript函數
我們在JavaScript環境定義一個加法函數然后.NET這邊調用拿到結果:
<script>function add(a, b) {return a + b;}</script>注意:JavaScript代碼要放到wwwroot/index.html頁面上里,不能直接放在組件里。
組件代碼:
<h3>.net call javascript</h3> sum: @sum <button @onclick="CallJs">Call Add </button> @inject IJSRuntime jsRuntime @code {private int sum = 0;private async void CallJs(){sum = await jsRuntime.InvokeAsync<int>("add", sum, 2);this.StateHasChanged();} }運行一下:
JavaScript調用.NET方法
JavaScript調用.NET靜態方法
JavaScript調用.NET靜態方法比較簡單,把靜態方法加上[JSInvokable],然后在JavaScript環境使用DotNet對象直接call就行:
定義.NET靜態方法:
使用JavaScript調用GetNow:
$(document).ready(setTimeout(() => {$('#btn1').on('click', function () {DotNet.invokeMethodAsync('BlazorWasmComponent', 'GetNow').then(data => {alert(data);});})}, 10000));由于Blazor渲染UI結束后按鈕才會插入到dom樹上,所以這里使用一個傻辦法讓綁定事件的JavaScript代碼置后運行。運行一下:
JavaScript調用組件里的方法
JavaScript調用組件里的方法比較繞,其實還是通過一個靜態方法作為入口,把實例方法綁定一個靜態delegate,然后讓這個靜態方法去執行delegate。
.NET代碼:
JavaScript代碼:
$(document).ready(setTimeout(() => {$('#btn1').on('click', function () {DotNet.invokeMethodAsync('BlazorWasmComponent', 'GetNow').then(data => {alert(data);});})}, 10000));運行一下:
調用對象的方法
Blazor還可以把.NET對象(引用)直接傳遞到JavaScript運行時來讓JavaScript直接調用.NET對象的方法。
總的來說大概分4步:
實例化.net對象
DotNetObjectReference.Create方法把.NET對象包裝
通過JSRuntime調用一個JavaScript方法把第二步生成的對象傳遞到JavaScript運行時
在JavaScript側通過invokeMethodAsync方法調用.NET對象里的方法
下面演示下把組件整個實例傳遞出去,然后調用里面的GetNowInInstance方法。
.net代碼:
<h3>javascript call .net</h3> <button id="btn1">Js call .net </button> @implements IDisposable @inject IJSRuntime jsRuntime @code {IDisposable _objRef;protected async override Task OnInitializedAsync(){_objRef = DotNetObjectReference.Create(this);await jsRuntime.InvokeAsync<string>("receiveNetObj",_objRef);base.OnInitialized();}[JSInvokable]public string GetNowInInstance(){return DateTime.Now.ToString();}public void Dispose(){_objRef?.Dispose();} }注意:把.NET對象傳遞到JavaScript運行時存在內存泄漏的風險,所以組件需要實現IDisposable接口,在Dispose方法內調用objRef的Dispose方法來釋放內存。
JavaScript代碼:
var _netObj = null;function receiveNetObj(obj) {_netObj = obj;}$(document).ready(setTimeout(() => {$('#btn1').on('click', function () {_netObj.invokeMethodAsync("GetNowInInstance").then(r => alert(r));})}, 10000));運行一下:
總結
使用JSRuntime可以在.NET里調用JavaScript的方法,這些方法必須是全局的,也就是掛載在window對象上的。
在JavaScript里調用.NET方法主要有兩種:
通過DotNet方式調用.NET的靜態方法
把.NET對象直接傳遞到JavaScript運行時來調用對象上的方法
相關內容
ASP.NET Core Blazor Webassembly 之 路由
ASP.NET Core Blazor Webassembly 之 數據綁定
ASP.NET Core Blazor Webassembly 之 組件
ASP.NET Core Blazor 初探之 Blazor WebAssembly
ASP.NET Core Blazor 初探之 Blazor Server
關注我的公眾號一起玩轉技術
總結
以上是生活随笔為你收集整理的ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互调的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做.NET开发多年,公司要我转Java.
- 下一篇: 浅议C#客户端和服务端通信的几种方法:R