web-dev-qa-db-ja.com

Asp.netコアのViewComponent間でViewDataを共有する方法

2つのViewComponentがあり、ViewDataまたは他の手法を使用してデータを共有し、メインビューでこのデータを使用したいのですが、これは方法ではなく、ViewComponentごとのViewDataは、両方のViewComponentのif条件が豊富な場合はnullになります。

public class OneViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(Page page, Zone zone)
    {
        //some operation

        string text = "one";

        if(ViewData["data"] != null)
        {
            ViewData["data"] = ViewData["data"].ToString() + text;
        }
        else
        {
            ViewData["data"] = text;
        }

        return View();
    }
}

public class TwoViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(Page page, Zone zone)
    {
        //some operation

        string text = "two";

        if(ViewData["data"] != null)
        {
            ViewData["data"] = ViewData["data"].ToString() + text;
        }
        else
        {
            ViewData["data"] = text;
        }

        return View();
    }
}
8
Mohammad Akbari

ViewDataViewBagと同じです。コントローラからビューにデータを転送する場合にのみ使用します。このため、私は常にビューモデルを好みます。

コンポーネント間でデータを転送するには、次の2つのオプションがあります。

TempData辞書の代わりにViewData辞書を使用する:次のパッケージをインストールする必要があります

_Install-Package Microsoft.AspNetCore.Mvc.ViewFeatures
_

Startupクラスに、この行を追加します

_services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
_

ConfigureServicesメソッドに。私はCookieTempDataProviderITempDataProviderの実装として使用しますが、SessionStateTempDataProviderを使用できます。

データをTempDataディクショナリに格納するには、次のコードを使用します。

_this.TempData["data"] = "my value";
_

TempDataからデータを取得するには、次のコードを使用します。

_var data = this.TempData["data"];
_

コンポーネントビューで使用するには:

_@this.TempData["data"]
_

_HttpContext.Items_辞書の使用:インストールするパッケージはありません。ビューコンポーネントクラスで、次のようにデータを_HttpContext.Items_ディクショナリに格納します。

_this.HttpContext.Items["data"] = "my value"; 
_

そして、これを行うことによって保存されたデータへのアクセス:

_var data = this.HttpContext.Items["data"];
_

コンポーネントビューでは、次のようにして保存されたデータを取得できます。

_@this.Context.Items["data"]
_

TempDataと_HttpContext.Items_の違い:_HttpContext.Items_とTempData辞書の主な違いは次のとおりです。

  • _HttpContext.Items_は、リクエストが終了するとクリアされます。
  • デフォルトでは、データが読み取られるとTempDataはクリアされます。データを保持するには、明示的にTempData.Keep()を呼び出す必要があります
  • TempDataを使用すると、ビューコンポーネントを簡単にテストできます。これは、タイプITempDataDictionaryのインターフェイスであり、問​​題なくモックできるためです。
9
CodeNotFound

これは、ViewComponentsがユースケースに適していないことを示しています。代わりに部分ビューを使用する必要があります。

パーシャルビューは、親のビューアクションのコンテキストで実行されます。さらに、モデルをパーシャル、つまり製品リストからの製品に渡すことができます。

_@Html.Partial("PartialName", customViewData)
_

上記の例では、パーシャルのモデルパラメーター@Html.Partial("PartialName", "one")@Html.Partial("PartialName", "two")として_"one"_および_"two"_を指定します。

ViewComponentsは、ロジックの再利用可能なブロックに似ていますおよびviewこれはコントローラー+アクションと同様に機能します。ただし、コントローラー+アクションとは異なり、ViewComponentは複数の場所で再利用できます。

ViewComponentsは自給自足であり、外部のデータに依存しないようにする必要があります。

これはさらに、アプリケーション関連のロジックをアクションからビューに移動しようとしていること、およびコントローラーアクションからのデータがビューが消費するために十分に準備されていないことを示しています。

コントローラのアクションには、ユーザー入力の検証、基盤となるアプリケーションコード(一般にサービスと呼ばれる)の呼び出し、ビューが使用するためのサービス結果の準備という3つの単純なタスクしかありません。そうは言っても、より良い解決策は、アクションでビューモデルを使用し(型指定されていないViewDataの代わりに)、必要なすべてのデータを準備してから、ビューにそのデータだけを表示させることです。

4
Tseng