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 之 .NET JavaScript互调的更多相关文章

  1. ASP.NET Core Blazor Webassembly 之 路由

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

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

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

  3. ASP.NET Core Blazor Webassembly 之 组件

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

  4. [Asp.Net Core] Blazor WebAssembly - 工程向 - 如何在欢迎页面里, 预先加载wasm所需的文件

    前言, Blazor Assembly 需要最少 1.9M 的下载量.  ( Blazor WebAssembly 船新项目下载量测试 , 仅供参考. ) 随着程序越来越复杂, 引用的东西越来越多,  ...

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

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

  6. ASP.NET Core Blazor WebAssembly实现一个简单的TODO List

    基于blazor实现的一个简单的TODO List 最近看到一些大佬都开始关注blazor,我也想学习一下.做了一个小的demo,todolist,仅是一个小示例,参考此vue项目的实现http:// ...

  7. ASP.NET Core Blazor 用Inspinia静态页模板搭建简易后台(实现菜单选中)

    Blazor 是一个用于使用 .NET 生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建丰富的交互式 UI. 共享使用 .NET 编写的服务器端和客户端应用逻辑 ...

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

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

  9. [Asp.Net Core] Blazor Server Side 扩展用途 - 配合CEF来制作带浏览器核心的客户端软件 (二) 可运行版本

    前言 大概3个星期之前立项, 要做一个 CEF+Blazor+WinForms 三合一到同一个进程的客户端模板. 这个东西在五一的时候做出了原型, 然后慢慢修正, 在5天之前就上传到github了. ...

随机推荐

  1. CF948B Primal Sport

    题目链接:http://codeforces.com/contest/948/problem/B 知识点: 素数 解题思路: \(f(x)\) 表示 \(x\) 的最大素因子.不难想到:\(X_1 \ ...

  2. 公众号使用微信sdk的正确姿势

    当我们做微信登录授权,微信公众号的分享,微信的h5支付等等等等的时候难免会用到微信sdk,当我们用react或vue做的spa应用,直接引入后会发现,在按安卓上可以正常调试,而ios上一直报签名错误( ...

  3. Java——变量自增(++)自减(--)

    //运算符在操作数之后,称为“后增量”.i变量自增,返回自增之前的值;//运算符在操作数之前,称为“前增量”.i变量自增,返回自增之后的值.//自减同理 public static void test ...

  4. PHP链式操作原理

    1)第一种方法 <?php /* *类功能:实现数据库的连贯查询操作 */ class mysql_query{ var $tbl=’user’;//要操作的表名 var $limit=”;// ...

  5. Layui 解决动态图标不动的问题

    <i class="layui-icon layui-icon-face-smile" style="color: red; font-size: 100px;&q ...

  6. 第3章 衡量线性回归的指标:MSE,RMSE,MAE

    , , ,, , ,  , 

  7. 微信小程序开发 -- 通过云函数下载任意文件

    微信小程序开发 -- 通过云函数下载任意文件 1.云开发介绍 ​ 微信小程序开发者众所周知,小程序开发拥有许多限制,当我还是一个菜鸟入门的时候,第一关就卡在了没有备案域名的HTTP请求上面,那时候云开 ...

  8. Redis学习笔记(3)

    一.Redis的事务(transaction) 1. 事务概念 本质:本质是一组命令的集合,所有的命令按照顺序一次性.串行化地执行,不允许其他命令的加入.Redis通过MULTI.EXEC.WATCH ...

  9. js中 addEventListener 和removeEventListener

    js中添加事件监听本来是非常常见的事情,但是去除监听一般很少去干,最近项目中需要监听页面显示或者隐藏 代码如下 document.addEventListener(visibilitychange', ...

  10. [PHP自动化-进阶]003.CURL处理Https请求访问

    引言:继前文<模拟登录并采集数据>,<模拟登录带有验证码的网站>,大家对CURL基本上已经有了认识,这一讲简单的说一下请求Https. 在很多的站点,如TalkingData, ...