(14/30)大家一起學Blazor:JavaScript interop(互通操作)

(14/30)大家一起學Blazor:JavaScript interop(互通操作)

雖然Blazor 不需要用到JavaScript,但某些已有的js庫 還是很方便,不能因為不想用JavaScript 就全部捨棄,Blazor 就提供了呼叫JavaScript 的方法,這種情況稱為JavaScript interoperability(簡稱JavaScript interop)。這篇就來實作Delete 按鈕的提醒視窗,因為刪除是很重要的功能,不能讓使用者輕輕一按就輕易刪除。

最後更新 2021/12/16 下午9:02
StrayaWorker
預計閱讀 4 分鐘
分類
Blazor
專題
一起學Blazor系列
標籤
.NET C# ASP.NET Core Blazor

雖然 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 官網下載檔案,接著將sweetalert.js放在<head>,然後把原本的第 4 種Blazor.start()移除,記得_framework/blazor.server.jsautostart="false"也要移除;或是直接寫在 Blazor.start()裡面也可以。

再加入自己的<script>,這邊比較特別的是用了Promise,Promise 是用來讓非同步更好用的語法,resolve的意思是執行成功後會回傳的內容(這邊執行成功的意思是没有例外狀況,也就是不論按下確定還是取消都會回傳)。

Confirm 方法則改成呼叫剛定義好的SweetConfirm()

點擊 Delete 按鈕,按下確定,willDelete為 true,於是resolve就將willDelete 傳回去,JsInteropClassesConfirm 成功收到了true(這裡有點小問題,點擊確定後,先彈出了刪除成功,JsInteropClasses才收到的true,後面有機會站長再優化)。

如果點擊取消,willDelete 是 null。

Promise 是前端避不掉的語法,有興趣的人可以看筆者附上的連結,筆者原本打算用 Observable 跟 subscribe 語法,不過 SweetAlert2 尚未實現。

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

最後來個本文效果動圖,結束本文:

引用:

  1. Blazor JavaScript interoperability (JS interop)
  2. Call JavaScript functions from .NET methods in ASP.NET Core Blazor
  3. HANDLING BUTTONS (CONFIRM, DENY, CANCEL)
  4. Day 20:JavaScript interop
  5. JavaScript Promise 全介紹
  6. Support ObservableLike #1982
  7. Blazor - Making a Promise in JS - SweetAlert2 Confirmation Dialog
  8. SweetAlert - upgrading-from-1x

註:本文程式碼透過 .NET 6 + Visual Studio 2022 重構,SweetAlert 使用的 2.0 版本,和原文出入較大,可點擊原文連結與重構後程式碼比較學習,謝謝閱讀。

繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 2021/12/25

(29/30)大家一起學Blazor:Blazor單元測試

開發一個系統最無聊的過程大概就是解決 Bug 了,尤其是那種嘗試對 null 物件取值的錯誤(`Object reference not set to an instance of an object.`),這應該是大部分人剛踏入程式設計領域最常碰到的問題,為了從枯燥的解決 Bug 過程解脫,這篇就來介紹`單元測試`。

繼續閱讀
同分類 / 同標籤 2021/12/25

(28/30)大家一起學Blazor:Policy-based authorization

之前有說到`ASP.NET Core Identity` 使用的是基於`Claim` 的驗證,其實`ASP.NET Core Identity` 有不同類型的授權方式,最簡單的`登入授權`、`角色授權`、`Claim 授權`,但上述幾種都是以一種方式實現:原則授權(`Policy-based authorization`)。

繼續閱讀