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运行时来调用对象上的方法

最新文章

  1. 相克军_Oracle体系_随堂笔记004-shared pool
  2. JavaScript常用函数之Eval()使用
  3. Oracle自动备份脚本(网上找到的资料)
  4. Naive Bayes理论与实践
  5. QTP实现功能测试的时候,当新版本的页面都改变了,应该如何解决
  6. [HIHO1260]String Problem I(trie树)
  7. ruby函数回调的实现方法
  8. IMPDP hangs, session wait “wait for unread message on broadcast channel”
  9. 动画Rig设置为Legacy
  10. Oracle 11g+oracle客户端(32位)+PL/SQL develepment的安装配置
  11. 工欲善其事:编辑器之神Vim(一)
  12. Excel相关问题
  13. NGINX详解
  14. 【Android应用开发】Android Studio 错误集锦 -- 将所有的 AS 错误集合到本文
  15. SpringBoot系列——Redis
  16. python 读取指定div的内容
  17. Effective Java 第三版——78. 同步访问共享的可变数据
  18. Jenkins:管理节点
  19. 前端学习 -- Css -- 否定伪类
  20. ubuntu 11.04 old sources.list

热门文章

  1. jsp获取当前日期
  2. 依赖工程开发,编译报错Command Libtool failed with a nonzero exit code
  3. vue-cli 如何修改或删除预设preset记录
  4. 软链接 vs. 硬链接
  5. 你以为只有马云会灌鸡汤?Linux 命令行也会!
  6. U-Learning 后端开发日志(建设中...)
  7. WordPress获取某个标签关联的分类
  8. MySQL的日期类型
  9. Java基础语法--分支结构
  10. linux-offen-used-commands