Day 14 JavaScript interop

虽然 Blazor 不需要用到 JavaScript,但某些已有的 library 还是很方便,不能因为不想用 JavaScript 就全部舍弃,Blazor 就提供了呼叫 JavaScript 的方法,这种情境称为 JavaScript interoperability(简称 JavaScript interop)。这篇就来实作 Delete 按钮的提醒视窗,因为删除是很重要的功能,不能让使用者轻轻一按就轻易删除。

Day 07 有说过,Blazor 有内建的 JavaScript Service,所以我们不用去 Startup.cs 依赖注入,在想使用的页面注入即可。如果想在 razor component 注入,只要输入@inject IJSRuntime js即可。
https://ithelp.ithome.com.tw/upload/images/20210914/20140893az52IkiXaP.png

接着将原本的returnPostId()改名为deletePost(),型别改为Task,里面的逻辑稍作修改,可以看到 JavaScript 也是用 EventCallback 的方式,除了会回传值的InvokeAsync,还有不回传值的InvokeVoidAsync可以用。第一个参数放的是 JS function 的名字,如果该 function 有要求参数,就依序放在後面即可。
https://ithelp.ithome.com.tw/upload/images/20210914/20140893J84llttIqO.png

那如果想要自己写 class 把这段程序封包起来,好享受强型别的优势呢?Blazor 也提供了做法。首先在Shared资料夹新增JsInteropClasses,里面只有做三件事,依赖注入、原本的 confirm 方法以及Dispose
https://ithelp.ithome.com.tw/upload/images/20210914/20140893CLTQxBYzQH.png

接着在PostBase.razor.cs一开始将 JS 注入进JsInteropClasses且继承IDisposable
https://ithelp.ithome.com.tw/upload/images/20210914/20140893ctrm4vcHhM.png

然後将原本的方法改成刚刚封装好的jsClass.Confirm()方法,最後再覆写Dispose方法。https://ithelp.ithome.com.tw/upload/images/20210914/2014089337w6mpHP5c.png

可以看到跟原本直接在PostBase.razor.cs叫用 JS 的confirm是一样的结果。
https://ithelp.ithome.com.tw/upload/images/20210914/201408932oeZIadYWr.png

在 Blazor 有4种方式可以载入 JS 档案,分别为:<head><body>、外部 JS script 以及在 Blazor 启动後载入,都是将需要的<script>置於_Host.cshtml(Blazor Server)或是index.html(Blazor WebAssembly),比较特别的是最後一种,所以这边说明一下。

我们在_Host.cshtml原本的_framework/blazor.server.js底下加入自己的 script,里面做的事情很简单只有console.log文字,要特别注意的是原本的 script 要加入一个 attributeautostart="false",这是告诉Blazor 不要自动启动程序,如果不加这个 attribute,就会得到这样的错误讯息。
https://ithelp.ithome.com.tw/upload/images/20210914/201408931aC50OZmF0.pnghttps://ithelp.ithome.com.tw/upload/images/20210914/20140893CVmDhOmMFQ.png

不过目前的删除视窗太阳春了,我们来换个套件,笔者看许多人使用了 SweetAlert2,所以也来试试看。

首先去 SweetAlert2 官网下载档案,接着将sweetalert2.all.min.js放在<head>,然後把原本的第4种Blazor.start()移除,记得_framework/blazor.server.jsautostart="false"也要移除;或是直接写在Blazor.start()里面也可以。
https://ithelp.ithome.com.tw/upload/images/20210914/20140893QFNktJnPaO.png
https://ithelp.ithome.com.tw/upload/images/20210914/20140893r0iK1oxEvM.pnghttps://ithelp.ithome.![https://ithelp.ithome.com.tw/upload/images/20210914/201408934qHOfXJVcr.pnghttps://ithelp.ithome.com.tw/upload/images/20210914/20140893a3Aq2fzKdA.pngcom.tw/upload/images/20210914/20140893SZOHbgVIpp.png](https://ithelp.ithome.com.tw/upload/images/20210914/20140893SZOHbgVIpp.png)

再加入自己的<script>,这边比较特别的是用了 Promise,Promise 是用来让非同步更好撰写的语法,resolve的意思是执行成功後会回传的内容(这边执行成功的意思是没有异常,也就是不论按下确定还是取消都会回传)。
https://ithelp.ithome.com.tw/upload/images/20210914/20140893M2i6jut5sh.png

Confirm 方法则改成呼叫刚定义好的SweetConfirm()
https://ithelp.ithome.com.tw/upload/images/20210914/20140893cOjdmePtTM.png

在网页打开 Dev tool 切换到 Sources 页签,点击 Delete 按钮,按下确定,可以看到 result 的 isConfirmed 跟 value 为 true,於是resolve就将 isConfirmed 传回去,JsInteropClasses 的 Confirm 成功收到了 true。
https://ithelp.ithome.com.tw/upload/images/20210914/20140893poUz78L6lT.pnghttps://ithelp.ithome.com.tw/upload/images/20210914/20140893EXFbJLldMZ.png

如果点击取消,isConfirmed 就是 false。
https://ithelp.ithome.com.tw/upload/images/20210914/20140893At5DpN5B5k.png

Promise 是前端避不掉的语法,有兴趣的人可以看笔者附上的连结,笔者原本打算用 Observable 跟 subscribe 语法,不过 SweetAlert2 尚未实作。

另外 SweetAlert2 目前也有Blazor版本可以使用,方法大同小异,如果真的不想碰 JS 的人可以试试看。

Ref: Blazor JavaScript interoperability (JS interop)

Ref: Call JavaScript functions from .NET methods in ASP.NET Core Blazor

Ref: HANDLING BUTTONS (CONFIRM, DENY, CANCEL)

Ref: Day 20:Javascript interop

Ref: JavaScript Promise 全介绍

Ref: Support ObservableLike #1982

Ref: Blazor - Making a Promise in JS - SweetAlert2 Confirmation Dialog


<<:  Day 2 - 原型: Figma

>>:  Day8-我要学冨樫停刊

Day4-基本功时间-好做先做!SampleCode解析

愿大家平安的台风日! ------------------------ 【一步API串烧金融大丰收】...

【在厨房想30天的演算法】Day 26 资讯安全与演算法 : 混成金钥密码系统

Aloha!又是我少女人妻 Uerica!我家狗狗每次做了什麽让我崩溃的事,只要泪眼汪汪的看着我,我...

@Day25 | C# WixToolset + WPF 帅到不行的安装包 [既有的自订栏位介接]

搞定好 画面了以後,现在要把既有的自订栏位给加进去, 先用"选择路径"的自订栏位...

Day 18:将你的 Angular 更新到最新版!

今天要来谈谈如何查看 Angular 应用程序的版本及更新。 首先,我们要先知道目前本机端的 Ang...

他可以坚持,或许我也可以

最近对於自己的未来产生了另一个茫然。 自己会什麽,能给别人什麽,别人又怎麽样会觉得那很棒。 每当遇到...