web-dev-qa-db-ja.com

Blazor-コンポーネントを動的に作成する方法

Blazorコンポーネントを動的に作成できるかどうかをテストしたいと思います。

これを行う方法が見つかりません。 this link にある動的コンテンツを少し試してみましたが、結果は出ていません。

7
Diemauerdk

バージョン0.2の場合、これはSteve Sandersonからの回答です。

今後は、RenderFragmentsをビルドするためのより良いAPIを実装する予定ですが、今のところは、

@CreateDynamicComponent();
@functions {
    RenderFragment CreateDynamicComponent() => builder =>
    {
        builder.OpenComponent(0, typeof(SurveyPrompt));
        builder.AddAttribute(1, "Title", "Some title");
        builder.CloseComponent();
    };
}

これらは非常に低レベルのAPI(文書化されていません)であるため、今すぐに多くの人がこれを行う必要がないことを願っています。このための上位レベルのAPIは後で提供されます。

見つかりました ここ

12
Flores

受け入れられた回答とこの回答の元のバージョンのコメントから判断すると、コンポーネントを動的に追加することには少し混乱があるかもしれません。これを達成するには(少なくとも)いくつかの方法があります(そして、これに関するいくつかの既存の質問、たとえば here )。それはすべて、「動的に」が何を意味するかによって異なります。

1)Razorコードで条件ステートメントを使用する

データまたはモデルの状態に基づいてコンポーネントを表示または非表示にするだけの場合、コンポーネントを動的にレンダリングする「通常の」方法は、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>
_

2. RenderFragmentを使用した動的レンダリング

上記の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の背景の場合)、新しいHTMLをDOMに手動で挿入したり、部分的なビューを動的にロードしたりする必要がないことです。君は。

MVCのかみそりページとBlazorのかみそりページの間の構文の類似性にもかかわらず、Blazorモデルは概念的にはMVCよりもReact=のようなものに近いです。バックグラウンドのシャドウDOMの行。

このページにはいくつかの良いポインタがあります Blazorのデータバインディング。

8
tomRedox