雖然 Blazor 不需要用到 JavaScript,但某些已有的 library 還是很方便,不能因為不想用 JavaScript 就全部捨棄,Blazor 就提供了呼叫 JavaScript 的方法,這種情境稱為 JavaScript interoperability(簡稱 JavaScript interop)。這篇就來實作 Delete 按鈕的提醒視窗,因為刪除是很重要的功能,不能讓使用者輕輕一按就輕易刪除。
Day 07 有說過,Blazor 有內建的 JavaScript Service,所以我們不用去 Startup.cs 依賴注入,在想使用的頁面注入即可。如果想在 razor component 注入,只要輸入@inject IJSRuntime js
即可。
接著將原本的returnPostId()
改名為deletePost()
,型別改為Task
,裡面的邏輯稍作修改,可以看到 JavaScript 也是用 EventCallback 的方式,除了會回傳值的InvokeAsync
,還有不回傳值的InvokeVoidAsync
可以用。第一個參數放的是 JS function 的名字,如果該 function 有要求參數,就依序放在後面即可。
那如果想要自己寫 class 把這段程式封包起來,好享受強型別的優勢呢?Blazor 也提供了做法。首先在Shared
資料夾新增JsInteropClasses
,裡面只有做三件事,依賴注入、原本的 confirm 方法以及Dispose
。
接著在PostBase.razor.cs
一開始將 JS 注入進JsInteropClasses
且繼承IDisposable
。
然後將原本的方法改成剛剛封裝好的jsClass.Confirm()
方法,最後再覆寫Dispose
方法。
可以看到跟原本直接在PostBase.razor.cs
叫用 JS 的confirm
是一樣的結果。
在 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,就會得到這樣的錯誤訊息。
不過目前的刪除視窗太陽春了,我們來換個套件,筆者看許多人使用了 SweetAlert2,所以也來試試看。
首先去 SweetAlert2 官網下載檔案,接著將sweetalert2.all.min.js
放在<head>
,然後把原本的第4種Blazor.start()
移除,記得_framework/blazor.server.js
的autostart="false"
也要移除;或是直接寫在Blazor.start()
裡面也可以。
再加入自己的<script>
,這邊比較特別的是用了 Promise,Promise 是用來讓非同步更好撰寫的語法,resolve
的意思是執行成功後會回傳的內容(這邊執行成功的意思是沒有異常,也就是不論按下確定還是取消都會回傳)。
Confirm 方法則改成呼叫剛定義好的SweetConfirm()
。
在網頁打開 Dev tool 切換到 Sources 頁籤,點擊 Delete 按鈕,按下確定,可以看到 result 的 isConfirmed 跟 value 為 true,於是resolve
就將 isConfirmed 傳回去,JsInteropClasses 的 Confirm 成功收到了 true。
如果點擊取消,isConfirmed 就是 false。
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: Support ObservableLike #1982
Ref: Blazor - Making a Promise in JS - SweetAlert2 Confirmation Dialog