原文鏈接:https://blazor-university.com/templating-components-with-renderfragements/passing-data-to-a-renderfragement/
將數據傳遞給 RenderFragment
源代碼[1]
到目前為止,我們使用了僅包含子標記的 RenderFragments
,然后在渲染組件時按原樣包含子標記。除了標準的 RenderFragment
類之外,還有一個通用的 RenderFragment<T>
類,可用于將數據傳遞到 RenderFragment
。
允許用戶指定模板
更改 TabControl
組件并在 ChildContent
參數下添加一個新的 TabTextTemplate
參數屬性。
[Parameter]
public?RenderFragment?ChildContent?{?get;?set;?}[Parameter]
public?RenderFragment<TabPage>?TabTextTemplate?{?get;?set;?}
然后更改 foreach 循環中的標記。我們需要做的是檢查是否設置了 TabTextTemplate
;如果沒有,那么我們照常渲染,如果已經設置,那么我們執行 TabTextTemplate RenderFragment
,從 foreach
循環中傳入 TabPage
。
<CascadingValue?Value="this"><div?class="btn-group"?role="group">@foreach?(TabPage?tabPage?in?Pages){<button?type="button"class="btn?@GetButtonClass(tabPage)"@onclick=@(?()?=>?ActivatePage(tabPage)?)>@if?(TabTextTemplate?!=?null){@TabTextTemplate(tabPage)}else{@tabPage.Text}</button>}</div>@ChildContent
</CascadingValue>
要設置 TabTextTemplate
,我們需要在使用 TabControl
的頁面中編輯標記。只需在 <TabControl>
元素內添加 <TabTextTemplate>
元素即可完成此操作,只要將 TabPage
的標記呈現到 TabControl
的選項卡中,該模板內的所有內容都將被視為要使用的 RenderFragment
。
<TabControl><TabTextTemplate>Hello</TabTextTemplate><TabPage?Text="Tab?1"><h1>The?first?tab</h1></TabPage><TabPage?Text="Tab?2"><h1>The?second?tab</h1></TabPage><TabPage?Text="Tab?3"><h1>The?third?tab</h1></TabPage>
</TabControl>
但是,一旦您這樣做,編譯器就會抱怨以下錯誤消息。
組件“TabControl”內無法識別的子內容。組件“TabControl”通過以下頂級項目接受子內容:“ChildContent”、“TabTextTemplate”。
當您的組件中只有一個 RenderFragment
參數并且它被命名為 ChildContent
時,Blazor 將假定每當我們使用該組件并在我們想要將其分配給 ChildContent
的開始和結束標記之間包含內容。但是一旦我們在消費者的標記中有兩個 RenderFragment
,Blazor 就不能假定所有內容都應該分配給 ChildContent
參數。此時,組件的用戶必須顯式創建一個 <ChildContent>
元素來保存內容。
為了明確意圖,可以將 ChildContent
屬性重命名為 Tabs
。
<TabControl><TabTextTemplate>Hello</TabTextTemplate><ChildContent><TabPage?Text="Tab?1"><h1>The?first?tab</h1></TabPage><TabPage?Text="Tab?2"><h1>The?second?tab</h1></TabPage><TabPage?Text="Tab?3"><h1>The?third?tab</h1></TabPage></ChildContent>
</TabControl>
在 RenderFragment 中訪問上下文
到目前為止,TabControl
組件將為每個 TabPage
的選項卡只顯示文本“Hello”。我們需要的是訪問正在呈現的 TabPage
,以便我們可以輸出其 Text
屬性的值。注意 TabControl
組件中 TabTextTemplate
的使用。
@if?(TabTextTemplate?!=?null){@TabTextTemplate(tabPage)}else{@tabPage.Text}
在 foreach
循環中創建了一個 HTML <button>
,并且在該按鈕中,前面的代碼用于輸出應顯示給用戶單擊的內容。如果 TabTextTemplate
為空,則呈現 @tabPage.Text
,但如果 TabTextTemplate
不為空(組件用戶已指定模板),則呈現模板,并傳入循環的當前 tabPage
以獲取上下文。
當使用 RenderFragment<T>
類的通用版本時,我們必須在渲染該片段時傳遞 <T>
的值。傳遞給片段的值可通過名為 context
的特殊變量獲得。然后可以使用它來準確確定要渲染的內容。在我們的例子中,我們希望使用一些額外的標記來呈現 TabPage.Text
屬性。
<TabTextTemplate><img?src="/images/tab.png"/>?@context.Text
</TabTextTemplate>
避免 @context 名稱沖突
如果名稱 context
與組件中的另一個標識符沖突,則可以通過在 RenderFragment
上使用 Context
屬性來指示 Blazor 逐個使用不同的名稱。
例如,前面演示的 TabTextTemplate 標記可以改為如下編寫。
<TabTextTemplate?Context="TheTab"><img?src="/images/tab.png"/>?@TheTab.Text
</TabTextTemplate>
參考資料
[1]
源代碼: https://github.com/mrpmorris/blazor-university/tree/master/src/TemplatedComponents/PassingDataToARenderFragment