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静态方法:

    [JSInvokable]public static string GetNow(){return DateTime.Now.ToString();}

使用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代码:

<h3>javascript call .net</h3>
<button id="btn1">Js call .net
</button>
@inject IJSRuntime jsRuntime
@code {[JSInvokable]public static string GetNow(){return Act("");}public static Func<string, string> Act;protected override void OnInitialized(){Act = GetNowInInstance;base.OnInitialized();}public string GetNowInInstance(string str){return DateTime.Now.ToString();}
}

JavaScript代码:

 $(document).ready(setTimeout(() => {$('#btn1').on('click', function () {DotNet.invokeMethodAsync('BlazorWasmComponent', 'GetNow').then(data => {alert(data);});})}, 10000));

运行一下:

调用对象的方法

Blazor还可以把.NET对象(引用)直接传递到JavaScript运行时来让JavaScript直接调用.NET对象的方法。

总的来说大概分4步:

  1. 实例化.net对象

  2. DotNetObjectReference.Create方法把.NET对象包装

  3. 通过JSRuntime调用一个JavaScript方法把第二步生成的对象传递到JavaScript运行时

  4. 在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方法主要有两种:

  1. 通过DotNet方式调用.NET的静态方法

  2. 把.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互调相关推荐

  1. ASP.NET Core Blazor Webassembly 之 渐进式应用(PWA)

    Blazor支持渐进式应用开发也就是PWA.使用PWA模式可以使得web应用有原生应用般的体验. 什么是PWA PWA应用是指那些使用指定技术和标准模式来开发的web应用,这将同时赋予它们web应用和 ...

  2. ASP.NET Core Blazor Webassembly 之 路由

    web最精妙的设计就是通过url把多个页面串联起来,并且可以互相跳转.我们开发系统的时候总是需要使用路由来实现页面间的跳转.传统的web开发主要是使用a标签或者是服务端redirect来跳转.那今天来 ...

  3. ASP.NET Core Blazor Webassembly 之 数据绑定

    上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件).这次继续学习Blazor的数据绑定相关的知识.当代前端框架都离不开数据绑定技术. ...

  4. ASP.NET Core Blazor Webassembly 之 组件

    关于组件 现在前端几大轮子全面组件化.组件让我们可以对常用的功能进行封装,以便复用.组件这东西对于搞.NET的同学其实并不陌生,以前ASP.NET WebForm的用户控件其实也是一种组件.它封装ht ...

  5. vs mfc数据与控件绑定错了_ASP.NET Core Blazor Webassembly 之 数据绑定

    上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件).这次继续学习Blazor的数据绑定相关的知识.当代前端框架都离不开数据绑定技术. ...

  6. 动态字段无法双向绑定_ASP.NET Core Blazor Webassembly 之 数据绑定

    上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件).这次继续学习Blazor的数据绑定相关的知识.当代前端框架都离不开数据绑定技术. ...

  7. 使用VS 2019,.NET Core 3和Web API创建ASP.NET Core Blazor CRUD应用程序

    目录 介绍 Blazor Blazor客户端应用程序 Blazor服务器应用程序 背景 先决条件 使用代码 第1步-创建数据库和表 第2步-创建ASP.NET Core Blazor服务器应用程序 运 ...

  8. ASP.NET Core Blazor 初探之 Blazor Server

    上周初步对Blazor WebAssembly进行了初步的探索(ASP.NET Core Blazor 初探之 Blazor WebAssembly).这次来看看Blazor Server该怎么玩. ...

  9. 用于存储过程的ASP.NET Core Blazor和EF Core原始SQL查询

    目录 介绍 背景 先决条件 使用代码 创建数据库和表 步骤1:创建ASP.NET Core Blazor服务器应用程序 运行测试应用程序 步骤2:安装软件包 连接字符串 步骤3:建立模型类 创建DBC ...

最新文章

  1. 全国计算机等级考试评卷、成绩处理和证书管理办法
  2. python能做游戏吗-python能做游戏吗
  3. 【转载】ceph作为OpenStack的后端存储解决方案
  4. js创建对象的高级模式
  5. Spring boot集成mongodb
  6. dorado-初学1
  7. 计算机安全 原理 资料_2019年山东地区计算机考研汇总分析
  8. 数据结构括号匹配代码_栈:如何实现有效括号的判断?
  9. linux 查看系统信息命令
  10. 集群、负载、并发介绍
  11. C语言的 typedef 关键字
  12. 联想打印机驱动安装报错
  13. Android平板软件推荐,Android平板电脑必备软件推荐
  14. SVN忽略设置的方法
  15. 昆明理工大学计算机考研资料汇总
  16. BAPI_PO_CREATE1 创建采购订单
  17. 安全策略篇 安全策略发展历程详解
  18. 大数据为湖湘互联网发展加码
  19. Linux最全面试题100问答,纯纯爽文
  20. STM32F4xx FPU和DSP库的使用

热门文章

  1. 常见浏览器兼容性问题与解决方案?
  2. DataGirdView 常用操作
  3. SQL对Xml字段的操作
  4. 持续集成之配置TeamCity
  5. beautiful sentences
  6. ecshop在首页调用dedecms文章
  7. 401 Palindrome
  8. 删除windows7中的“兼容性疑难解答”右键菜单
  9. 使用mintty(_如何使用Mintty改善Cygwin控制台
  10. linux 下eclipse调试程序,文章2 Linux安装Eclipse阅读及调试程序