對於版本0.2,這是史蒂夫·桑德森的答案:
將來,我們將實現更好的API來構建RenderFragments,但現在您可以
@CreateDynamicComponent(); @functions { RenderFragment CreateDynamicComponent() => builder => { builder.OpenComponent(0, typeof(SurveyPrompt)); builder.AddAttribute(1, "Title", "Some title"); builder.CloseComponent(); }; }
這些都是非常底層的API(甚至沒有文檔),因此我們希望現在沒有多少人需要這樣做。稍後將提供更高級別的API。
在這裡找到
從對接受的答案和該答案的原始版本的評論來看,我認為在動態添加組件方面可能會有些混亂。有(至少)幾種方法可以實現這一目標(以及與此相關的許多現有問題,例如此處 )。這完全取決於您“動態”的意思:
如果您要實現的只是基於數據或模型中某些狀態顯示或隱藏組件,則動態呈現組件的“正常”方法是在Razor視圖中使用某種條件代碼。
@if (_showCounter)
{
<MyCounterComponent Count="@_count" />
}
@code {
bool _showCounter = true;
int _count;
}
對於重複的數據集(例如項目列表),您可以利用Blazor的數據綁定。
以顯示銷售訂單的頁面/組件為例,然後每個銷售訂單行都有一個子組件。您的剃須刀頁面上可能具有如下所示的代碼:
@foreach (var salesOrderLine in _salesOrder.salesOrderlines)
{
<SalesOrderLine SOLine=@salesOrderLine />
};
如果您有一個添加了另一個銷售訂單行的按鈕,則只需在按鈕單擊事件中將新記錄添加到_salesOrder
模型/視圖模型中即可。通常,單擊按鈕會觸發重新渲染,因此頁面應自動顯示一個額外的SalesOrderLine
組件(如果沒有,則可以使用this.StateHasChanged();
告訴它有所不同並導致重新渲染)
如果您的列表包含不同類型,則可以使用switch語句來決定要呈現的組件類型,例如(來自此github問題 ):
<ul> @foreach (fruit in fruits) { switch(fruit) { case PearComponent p: <PearComponent ParameterOfSomeSort="p"></PearComponent> <li>Or render pears like this, if you want the li in it</li> break; case AppleComponent a: <AppleComponent></AppleComponent> break; case BananaComponent b: <BananaComponent></BananaComponent> break; case RaspberryComponent r: <RaspberryComponent></RaspberryComponent> break; } } </ul>
在某些情況下,使用上面的Razor方法無法很好地處理。在這種情況下, RenderFragment
提供了另一種動態呈現頁面部分的方式。
如果您有一個真正的多態列表(例如,全部實現相同接口或從同一類繼承的對象的列表),則可以使用這種方法( 來自此github帖子 ):
@page "/" @foreach (CounterParent counter in components) { RenderFragment renderFragment = (builder) => { builder.OpenComponent(0, counter.GetType()); builder.CloseComponent(); }; <div> <div>Before the component</div> @renderFragment <div>Afterthe component</div> </div> } @code { List<CounterParent> components = new List<CounterParent>() { new CounterParent(), new CounterChild() }; }
Blazor團隊正在考慮改進 Blazor 中處理多態列表的方式
這裡的關鍵點(對於那些來自MVC背景的人)是,無需像在MVC中那樣嘗試將新的HTML手動注入DOM或動態加載部分視圖,Blazor會這樣做您。
儘管MVC的剃刀頁面和Blazor的剃刀頁面在語法上相似,但Blazor模型在概念上更接近於React之類,而不是MVC,了解背景中的影子DOM確實很重要。