1. 程式人生 > >ASP.NET Core Blazor Webassembly 之 資料繫結

ASP.NET Core Blazor Webassembly 之 資料繫結

上一次我們學習了Blazor元件相關的知識([Asp.net Core Blazor Webassembly - 元件](https://www.cnblogs.com/kklldog/p/blazor-webassembly-component.html))。這次繼續學習Blazor的資料繫結相關的知識。當代前端框架都離不開資料繫結技術。資料繫結技術以資料為主導來驅動UI介面,使用者對資料的修改會實時提現在UI上,極大的提高了開發效率,讓開發者從繁瑣的dom操作中解脫出來。對於資料繫結.NET開發者並不會陌生,WPF裡大量應用資料繫結技術,有過WPF開發經驗的同學其實很容易理解前端的資料繫結。總之資料繫結技術及其概念、思維極其重要。下面讓我們看看Blazor的資料繫結技術。 ## 單向繫結 Blazor的資料繫結官方文件是直接從雙向繫結開始的,但我覺得有必要說一下單向繫結。因為其他框架一般都會區分單向、雙向,比如vue的v-bind單向,v-model就是雙向。我們這裡分開講也有利於跟其他框架進行對比。下面我們實現一個計數器元件來演示下單向資料繫結。 ### 使用@進行繫結 ``` @page "/counter"

Current count: @currentCount

@code { private int currentCount = 0; private void IncrementCount() { currentCount++; } } ``` 這個Counter元件預設的專案就自帶。跟我們使用服務端Razor一樣,使用@符號在需要替換值的地方插入對應的變數。這個值就會被渲染在相應的地方。當我們在前端修改變數的時候,對應的ui介面會同步進行修改。 ![](https://s1.ax1x.com/2020/06/01/t8trng.gif) ### 使用@bind-{attribute}進行繫結 除了直接使用@進行繫結,我們還可以使用@bind-{attribute}來實現對html元素屬性的繫結,比如對style,class內容進行繫結。下面演示下對class進行繫結。我們把p元素的class繫結到“currentClass”欄位。 ``` @page "/counter"

Counter

current count: @currentCount

@code { private string currentClass = "text-danger"; private int currentCount = 0; private void IncrementCount() { currentCount++; } } ``` ![](https://s1.ax1x.com/2020/06/01/t84WjS.png) 使用@bind-{attribute}進行繫結有個比較奇怪的問題,當你使用@bind-{attribute}進行繫結的時候必須同時指定@bind-{attribute}:event。@bind-{attribute}:event是用來指定雙向繫結的時候控制元件在發生某個事件的時候回寫值到繫結的欄位上。可是p,div這種元素根本不可能會激發onchange,oninput這種事件,也不可能去修改繫結的欄位的值,這個用法感覺有點多此一舉。 Blazor的單向資料繫結的用法跟ASP.NET Core MVC的Razor基本相似,不同點就是Blazor不需要Http回發到伺服器就可以實時渲染新的介面出來。 ## 雙向繫結 雙向繫結主要使用在一些輸入控制元件上,比如input,select等。當我們對這些控制元件上的值進行修改後會回寫繫結的欄位。這種特性在表單場景中非常有用。我們定義一個使用者資訊編輯的元件來演示下: ``` @page "/infoedit"

userName: @userName

sex: @sex

userName:

sex:

@code { private string userName="abc"; private string sex="f"; } ``` ![t8HBB8.md.gif](https://s1.ax1x.com/2020/06/01/t8HBB8.gif) 當我們執行這個元件,在文字框進行修改後,滑鼠點選其他地方讓文字框失去焦點值就會回寫到繫結的欄位上,上面的單向繫結資訊會自動同步。但是如果你用過VUE或者Angularjs的雙向繫結就會覺得失去焦點再回寫欄位資料太慢了,一點也不酷。要知道VUE的雙向繫結可是實時同步的,那麼Blazor如何做到在輸入的同時就更新值呢,答案是使用@bind:event來指定回寫的激發事件,我們改成“oninput”事件就可以實現: ```

userName:

``` ![](https://s1.ax1x.com/2020/06/01/t8OPC4.gif) ### 雙向繫結的多種寫法 看到這裡也許你也明白了,@bind真正的本質是由對value的繫結和對某個事件的繫結協同完成的。這點跟VUE非常相似。@bind其實是@bind-value的縮寫,我們可以用@bind-value來實現雙向繫結: ```

userName:

``` 以上寫法的效果跟@bind一模一樣。再進一步,@bind-value也只是對@的包裝,我們可以使用@來實現雙向繫結: ``` @page "/infoedit"

userName: @userName

sex: @sex

userName:

sex:

@code { private string userName="abc"; private string sex="f"; private void oninput(ChangeEventArgs e) { userName = e.Value.ToString(); } } ``` 以上程式碼的效果跟@bind一模一樣。通過使用@對value直接進行繫結以及繫結一個oninput事件進行值的回寫,同樣實現了雙向繫結。 ## 格式化時間字串 使用@bind:format 可以對繫結時間型別欄位的時候進行格式化: ``` 出生日期: ``` ![t8xrfU.png](https://s1.ax1x.com/2020/06/01/t8xrfU.png) 這個功能有點類似Angularjs的filter功能,但是目前只能對時間進行格式化,功能很弱。 ## 父元件繫結資料到子元件 元件之間往往都是巢狀的,很多子元件都依賴父元件的資料來決定如何呈現,這種場景非常常見。我們還是繼續修改上面的編輯元件,使用者資訊不在自己初始化,而是從父元件傳遞過來: 子元件: ``` ====================child==================

userName:

sex:

BrithDay:

@code { [Parameter] public UserInfo UserInfo { get; set; } [Parameter] public EventCallback