今天要來介紹第二批的關鍵字 Razor 指示詞屬性,與昨天的不同,是需要寫在 HTML 元素屬性上,所以即便有著同樣的名稱,但意義是不同的喔。


@attribute

@attribute 指示詞屬性針對該 HTML 元素屬性添加額外的屬性,也就是屬性展開。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<input id="useAttributesDict"
@attributes="InputAttributes" />

@code {
public string maxlength = "10";
public string placeholder = "Input placeholder text";
public string required = "required";
public string size = "50";

public Dictionary<string, object> InputAttributes { get; set; } =
new Dictionary<string, object>()
{
{ "maxlength", "10" },
{ "placeholder", "Input placeholder text" },
{ "required", "required" },
{ "size", "50" }
};
}

轉譯的元素為:

1
2
3
4
5
<input id="useAttributesDict"
maxlength="10"
placeholder="Input placeholder text"
required="required"
size="50">

若有大量重複屬性時,可以提取並共用。

@bind

@bind 指示詞屬性針對該 HTML 元素屬性綁定對應的欄位、屬性甚至是運算式值。

1
2
3
4
5
<input @bind="currentValue" /> Current value: @CurrentValue

@code {
private string currentValue { get; set; }
}

後續文章將針對資料繫結詳細介紹。

@on{Event}

@on{Event} 指示詞屬性用於事件處理,也就是處理瀏覽器發出的事件,讓我們可以掌握使用者的操作,加以顯示對應的頁面邏輯。

1
2
3
4
5
6
7
8
<input type="checkbox" @onchange="CheckChanged" />

@code {
private void CheckChanged()
{
...
}
}

與他的二弟 @on{EVENT}:preventDefault 和三弟 @on{EVENT}:stopPropagation 都會在後續文章將針對事件處理詳細介紹。

@key

@key 指示詞屬性使 Blazor 比較運算法保證根據索引鍵的值來保留元素或元件:

1
2
3
4
5
6
7
8
9
@foreach (var person in People)
{
<DetailsEditor @key="person" Details="@person.Details" />
}

@code {
[Parameter]
public IEnumerable<Person> People { get; set; }
}

這邊再補充一下,Blazor 在轉譯元素或元件以及其後續變更時,會透過比較演算法來決定哪些元素或元件是可以保留的,以及模型物件如何對應到這些元素或元件。

一般來說,這些都是自動的,但在某些情況下我們可能需要控制這個流程,這時就需要借助 @key 的幫助了。

使用 @key 可以最大程度的減少重新渲染的複雜性,並避免變更 DOM 的可設定狀態部分,例如替換內容時依然可以保留焦點位置。

以上優點都是針對保留來說明,但能保留也就意味著可以不保留,如果情境是一定要捨棄掉內容時,我們也可以使用:

1
2
3
<div @key="currentPerson">
... content that depends on currentPerson ...
</div>

currentPerson 的值變更時 Blazor 會強制捨棄整個 <div> 與其內容,並使用新的元素和元件來重建 UI 內的子樹,保證變更時不會保留任何的 UI 狀態。

即使沒使用 @key,Blazor 也會盡可能的保留子項目和元件實例。

@ref

@ref 指示詞屬性用於取得該子元件的實例參考。

1
2
3
4
5
6
7
8
9
10
<CustomLoginDialog @ref="loginDialog" ... />

@code {
private CustomLoginDialog loginDialog;

private void OnSomething()
{
loginDialog.Show();
}
}

後續文章將針對元件詳細介紹。


以上就是我認為的所有指示詞屬性,這邊的我認為是因為目前的官方文件中 @typeparam 也被歸類於這一系列,但我覺得是官方文件寫錯了,或者單純是我對於指示詞屬性這個分類理解有問題,因為 @typeparam 並不是寫在元素裡,是與指示詞相同的位置,應該屬於指示詞,還請哪個路過的大神指正,而 @typeparam 會在之後針對樣板化元件詳細介紹。

感謝大家的閱讀,我們明天見。

參考來源
Razor 語法 - 指示詞屬性
屬性展開和任意參數
使用 @ 金鑰來控制元素和元件的保留