iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
自我挑戰組

ASP.NET Core & Blazor系列 第 14

Day 14 JavaScript interop

  • 分享至 

  • xImage
  •  

雖然 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

再加入自己的<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 13 EventCallback, event from child to parent
下一篇
Day 15 CSS isolation
系列文
ASP.NET Core & Blazor30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言