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

    [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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode654. 最大二叉树

一:上码 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

浅议C#客户端和服务端通信的几种方法:Rest和GRPC和其他

本文来自&#xff1a;https://michaelscodingspot.com/rest-vs-grpc-for-asp-net/浅议C#客户端和服务端通信的几种方法&#xff1a;Rest和GRPC在C&#xff03;客户端和C&#xff03;服务器之间进行通信的方法有很多。一些功能强大&#xff0c;而其他功能则不是很多。有些非常快…

leetcode106. 从中序与后序遍历序列构造二叉树(java详解版)

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

COSCon’20开源教育论坛介绍

点击上方“开源社”关注我们| 作者&#xff1a;周添一| 编辑&#xff1a;沈于蓝| 设计&#xff1a;冯艺怡| 责编&#xff1a;王皓月论坛简介在当今数据驱动的智能社会&#xff0c;软件作为数字智能社会的数据基础设施&#xff0c;承载了社会的高效运转。在这个软件定义世界的潮…

leetcode105. 从前序与中序遍历序列构造二叉树

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

想进BAT等大厂,到底要怎么做?

职场&认知洞察 丨 作者 / findyi这是findyi公众号的第82篇原创文章最近我的公众号多了很多学生读者&#xff0c;很多人问我&#xff1a;如果要进BAT等大厂&#xff0c;我是应该直接工作还是考研&#xff1f;对于未来要从事程序员行业的朋友来说&#xff0c;要不要考研&…

.NET 5.0 RC 2 发布,正式版将在 11 月 .NET Conf 大会上发布

原文&#xff1a;http://dwz.win/ThX作者&#xff1a;Richard翻译&#xff1a;精致码农-王亮说明&#xff1a;1. 本译文舍弃了少许我实在不知道如何翻译但又不是很重要的语句。2. 本文有不少超链接&#xff0c;由于微信公众号和头条平台外链会被剔除 URL 地址&#xff0c;所以原…

leetcode216. 组合总和 III

一:题目 二:上码 class Solution {/**递归深度根据k值确定,宽度的话那就[1,9]因为递归不允许重复&#xff0c;那么的话我们需要每次在横向遍历的起始位置1*/private List<List<Integer>> ans new ArrayList<>();private List<Integer> path new Arr…

BeetleX之Websocket协议分析详解

Websocket应用协议已经普及多年了&#xff0c;它是HTTP1.1的内部升级协议&#xff0c;主要作用是补充HTTP1.1无法灵活地主动推送消息给客户端的缺陷问题。在这里主要介绍一下使用组件如何扩展一个完整的Websocket协议。协议介绍Websocket并不复杂&#xff0c;但协议文档内容还是…

甲骨文是否可以要求 Java API 享有版权?这场10年官司怎么结

美国最高法院10月7日就 Oracle 甲骨文诉 Google 谷歌一案进行口头辩论。案件一直以来争议的核心是&#xff0c;甲骨文是否可以要求 Java API 享有版权&#xff0c;如果可以&#xff0c;那么谷歌是否侵犯了这些版权&#xff1f;Java API 是否可以享有版权&#xff1f;Sun 公司在…

C#知多少 | 每个版本都更新了什么?

总所周知&#xff0c;.NET5.0马上就要来了&#xff0c;最后一个预览版RC2也已经发布了&#xff0c;在11月的时候&#xff0c;我们就正式的发布了&#xff0c;然后我们就可以迁移使用了&#xff0c;当然今天说的重点不是.NET&#xff0c;今天说的是伴随着.NET5一起到来的C#9.0&a…

leetcode40. 组合总和 II(树层去重)

一:题目 二:上码 class Solution {/**注意这里的去重:1.我们分为树层去重比如[1,1 2,5] target 8,那么如果我们用树枝去重的话,那么就会出现[1,2,5],[1,2,5]那么的话我们就需要树层去重 就是横向遇见相同的元素跳过。2.树枝去重的 树枝去重就是 我们数组前面使用过的元素不…

WPF开源控件扩展库 - MaterialDesignExtensions

WPF开源控件扩展库 - MaterialDesignExtensionsMaterialDesignExtensions仓库截图logoMaterial Design Extensions 在WPF开源控件库 ????Material Design in XAML Toolkit(本站介绍&#xff1a;????链接)的基础上进行了控件扩展和特性新增。本开源项目中的控件或许不在…

leetcode131. 分割回文串

一:题目 二:上码 class Solution {/**思路:1.纵向递归的话 我们递归深度是 我们的 切割线切到了最后 2.横向for 我们的宽度就是字符串宽度3.在哪截取的话 那就是在哪个坐标的后面*/List<List<String>> ans new ArrayList<>();List<String> path n…

WordPress 已过时?创始人与新架构拥护者开战

喜欢就关注我们吧&#xff01;近日&#xff0c;WordPress 创始人 Matt Mullenweg 与 Netlify 首席执行官 Matt Biilmann 展开了一场口水战&#xff0c;双方就 WordPress 与新兴 WEB 应用架构 JAMStack 孰优孰劣进行了激烈的辩论。何为 JAMStack?JAMStack 是一种将 Web 应用部署…

leetcode93. 复原 IP 地址(思路+详解)

一:题目 二:上码 class Solution {/**思路: 1.跟分割字符串差不多,但是我们需要记录添加的.的个数 当其个数等于3的时候 我们就已经切割成4段了。2.判断字符是否合法1>:以0开头的数字不合法2>:遇见非数字字符不合法3>:大于255不合法*/private List<String> an…

今天的你,又被带节奏了吗?

这是头哥侃码的第220篇原创十一期间&#xff0c;我在某微信群看到几个哥们在讨论 与「带节奏」有关的话题。很显然&#xff0c;像这种略带吐槽的的话题是很容易引起共鸣的。于是你一句他一句的&#xff0c;用自带表情包的方式开始说起了「带节奏」的各种操作。先是A君&#xff…

谷歌最终还是把Knative交了出来

谷歌方面正计划将其开源 Knative 项目的直接控制权让渡给一个指导委员会。Knative 是谷歌开源的一套 Serverless 架构方案&#xff0c;它扩展了 Kubernetes&#xff0c;专注于解决容器为核心的 Serverless 应用的构建、部署和运行的问题&#xff0c;它构建在 Kubernetes 和 Ist…

你那么普通 所以一定要自信啊

你这么普通&#xff0c;必须自信啊 ​ 昨天讲到&#xff0c;不管你准没准备好&#xff0c;该来的都来了。只要你进入了社会&#xff0c;这一切都没得选&#xff0c;好的坏的甭管啥事&#xff0c;都一股脑摆在你面前&#xff0c;你必须要处理。你说我不行啊&#xff0c;我做不到…

leetcode293周赛6064. 不含特殊楼层的最大连续楼层数

一:题目 二:上码 // class Solution { // public:// bool find(vector<int>& v,int i) { // for (auto nums:v) { // if (nums i) return true;//包含某个数 就返回true // } // return false; // }// int maxCon…