雖然Blazor 不需要用到JavaScript,但某些已有的js庫 還是很方便,不能因為不想用JavaScript 就全部捨棄,Blazor 就提供了調用JavaScript 的方法,這種情況稱為JavaScript interoperability(簡稱JavaScript interop)。這篇就來實現Delete 按鈕的提醒窗口,因為刪除是很重要的功能,不能讓使用者輕輕一按就輕易刪除。
Day 07 有說過,Blazor 有內置的JavaScript Service,所以我們不用去Program.cs 依賴注入,在想使用的頁面注入即可。如果想在razor組件注入,只要輸入@inject IJSRuntime js即可。
接著將原本的ReturnPostId()改名為DeletePost(),類型改為Task,裡面的邏輯稍作修改,可以看到JavaScript 也是用EventCallback 的方式,除了會回傳值的InvokeAsync,還有不回傳值的InvokeVoidAsync可以用。第一個參數放的是JS方法 的名字,如果該JS方法有要求參數,就依序放在後面即可。
那如果想要自己寫C# 類把這段程序封裝起來,好享受強類型的優勢呢?Blazor 也提供了做法。首先在Shared文件夾新增JsInteropClasses.cs,裡面只有做三件事,依賴注入、原本的confirm 方法以及Dispose。
接著在PostBase.razor.cs一開始將JS 注入進JsInteropClasses且繼承IDisposable。
然後將原本的方法改成剛剛封裝好的_jsClass.Confirm()方法,最後再重寫Dispose方法。
可以看到跟原本直接在PostBase.razor.cs調用JS 的confirm是一樣的結果,差點忘了在Post.razor裡修改Delete按鈕的點擊事件回調方法為DeletePost。
在Blazor 有4個地方可以載入JS文件,分別為:<head>、<body>、外部JS script 以及在Blazor 啟動後載入,都是將需要的<script>置於_Layout.cshtml(Blazor Server)或是index.html(Blazor WebAssembly),比較特別的是最後一種,所以這邊說明一下。
我們在_Layout.cshtml原本的_framework/blazor.server.js底下加入自己的script,裡面做的事情很簡單只有console.log文字,要特別注意的是原本的script 要加入一個attribute autostart="false",這是告訴Blazor 不要自動啟動程序,如果不加這個attribute,就會得到這樣的錯誤訊息。
不過目前的刪除窗口太難看了,我們來換個套件,筆者看許多人使用了SweetAlert2,所以也來試試看。
首先去SweetAlert2[1] 官網下載文件,接著將sweetalert.js放在<head>,然後把原本的第4種Blazor.start()移除,記得_framework/blazor.server.js的autostart="false"也要移除;或是直接寫在Blazor.start()裡面也可以。
再加入自己的<script>,這邊比較特別的是用了Promise,Promise 是用來讓異步更好用的語法,resolve的意思是執行成功後會回傳的內容(這邊執行成功的意思是沒有異常,也就是不論按下確定還是取消都會回傳)。
Confirm 方法則改成調用剛定義好的SweetConfirm()。
點擊Delete 按鈕,按下確定,willDelete為true,於是resolve就將willDelete 傳回去,JsInteropClasses 的Confirm 成功收到了true(這裡有點小問題,點擊確定後,先彈出了刪除成功,JsInteropClasses才收到的true,後面有機會站長再優化)。
如果點擊取消,willDelete 是null。
Promise 是前端避不掉的語法,有興趣的人可以看筆者附上的連結,筆者原本打算用Observable 跟subscribe 語法,不過SweetAlert2 尚未實現。
另外SweetAlert2 目前也有Blazor版本[2]可以使用,方法大同小異,如果真的不想碰JS 的人可以試試看。
最後來個本文效果動圖,結束本文:
引用:
出處:iT邦幫忙
作者:StrayaWorker
原文連結:https://ithelp.ithome.com.tw/articles/10263798
編輯:沙漠盡頭的狼
註:本文代碼通過 .NET 6 + Visual Studio 2022重構,SweetAlert使用的2.0版本,和原文出入較大,可點擊上面的原文連結與重構後代碼比較學習,謝謝閱讀。
參考資料[1]SweetAlert2: https://sweetalert.js.org
[2]Blazor版本: https://github.com/Basaingeal/Razor.SweetAlert2
[3]Blazor JavaScript interoperability (JS interop): https://docs.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-5.0
[4]Call JavaScript functions from .NET methods in ASP.NET Core Blazor: https://docs.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-5.0
[5]HANDLING BUTTONS (CONFIRM, DENY, CANCEL): https://sweetalert2.github.io/#handling-buttons
[6]Day 20:Javascript interop: https://ithelp.ithome.com.tw/articles/10249044
[7]JavaScript Promise 全介紹: https://wcc723.github.io/development/2020/02/16/all-new-promise/
[8]Support ObservableLike #1982: https://github.com/sweetalert2/sweetalert2/issues/1982
[9]Blazor - Making a Promise in JS - SweetAlert2 Confirmation Dialog: https://www.youtube.com/watch?v=P1nMiVpptGk
[10]SweetAlert - upgrading-from-1x: https://sweetalert.js.org/guides/#upgrading-from-1x