博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互调
阅读量:4034 次
发布时间:2019-05-24

本文共 3882 字,大约阅读时间需要 12 分钟。

Blazor WebAssembly可以在浏览器上跑C#代码,但是很多时候显然还是需要跟JavaScript打交道。比如操作dom,当然跟angular、vue一样不提倡直接操作dom;比如浏览器的后退导航。反之JavaScript也有可能需要调用C#代码来实现一些功能,毕竟客户的需求是千变万化的,有的时候只能通过一些hack的手段来实现。

.NET调用JavaScript函数

使用JSRuntime.InvokeVoidAsync调用无返回值的JavaScript函数

显然我们的.NET类库里不会有JavaScript内置的alert方法来显示提示,这里演示下如何调用JavaScript的alert方法:

.net call javascript

@inject IJSRuntime jsRuntime@code { private void CallJs() { jsRuntime.InvokeVoidAsync("alert", "this message from .net runtime ."); }}

使用JSRuntime.InvokeVoidAsync调用具有返回值的JavaScript函数

我们在JavaScript环境定义一个加法函数然后.NET这边调用拿到结果:

注意:JavaScript代码要放到wwwroot/index.html页面上里,不能直接放在组件里。

组件代码:

.net call javascript

sum: @sum@inject IJSRuntime jsRuntime@code { private int sum = 0; private async void CallJs() { sum = await jsRuntime.InvokeAsync
("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代码:

javascript call .net

@inject IJSRuntime jsRuntime@code { [JSInvokable] public static string GetNow() { return Act(""); } public static Func
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代码:

javascript call .net

@implements IDisposable@inject IJSRuntime jsRuntime@code { IDisposable _objRef; protected async override Task OnInitializedAsync() { _objRef = DotNetObjectReference.Create(this); await jsRuntime.InvokeAsync
( "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运行时来调用对象上的方法

相关内容

关注我的公众号一起玩转技术

转载地址:http://ickdi.baihongyu.com/

你可能感兴趣的文章
course_2_assessment_6
查看>>
coursesa课程 Python 3 programming course_2_assessment_7 多参数函数练习题
查看>>
coursesa课程 Python 3 programming course_2_assessment_8 sorted练习题
查看>>
visca接口转RS-232C接口线序
查看>>
在unity中建立最小的shader(Minimal Shader)
查看>>
1.3 Debugging of Shaders (调试着色器)
查看>>
关于phpcms中模块_tag.class.php中的pc_tag()方法的含义
查看>>
vsftp 配置具有匿名登录也有系统用户登录,系统用户有管理权限,匿名只有下载权限。
查看>>
linux安装usb wifi接收器
查看>>
用防火墙自动拦截攻击IP
查看>>
补充自动屏蔽攻击ip
查看>>
谷歌走了
查看>>
多线程使用随机函数需要注意的一点
查看>>
getpeername,getsockname
查看>>
让我做你的下一行Code
查看>>
浅析:setsockopt()改善程序的健壮性
查看>>
关于对象赋值及返回临时对象过程中的构造与析构
查看>>
VS 2005 CRT函数的安全性增强版本
查看>>
SQL 多表联合查询
查看>>
Visual Studio 2010:C++0x新特性
查看>>