14

KnockoutJS を既存のアプリに導入しています。私の計画は、既に作成した既存の部分ビューを変更/利用し、それらを Knockout の宣言属性を使用して JS ビュー モデルにバインドすることです。アクションに対して AJAX 呼び出しを行う場合、理想的には、アクションが部分ビューの HTML と JSON オブジェクトの両方を返すようにしたいと考えています。次に、div に HTML を入力し、JSON を Knockout オブジェクトに変換して、それを HTML にバインドします。しかし、アクションから両方を返す方法がわかりません。

更新して最終的にサーバーに送り返すため、完全なビュー モデルが必要です。

アクションが部分ビュー (既にモデルにバインドされている) を返し、部分ビュー内に .Net モデルを Knockout オブジェクトに変換する JavaScript を含めることを考えました。でも、そんなJSをばらまくのは面倒だし、メンテもままならない気がします。元の ajax 呼び出しにすべてを近づけたいと思います。

もう 1 つの方法は、2 つのアクション コールを行うことだと思います。1 つは JSON 用、もう 1 つは部分ビュー用です。しかし、よりスマートな方法が必要です。

これを行う最善の方法についてのアイデアはありますか?

4

2 に答える 2

22

これを行うにはさまざまな方法があると確信しています。コントローラーからビューを手動でレンダリングし、レンダリングされたビューを JSON 応答の一部として返します。

これにより、各エンティティの責任が保持されます。ビューは引き続きビュー エンジンを使用して配置され、再利用できます。コントローラーは、名前とモデル タイプ以外のビューについてほとんど、またはまったく知りません。

手動レンダリング

public static class RenderHelper
{
    public static string PartialView( Controller controller, string viewName, object model )
    {
        controller.ViewData.Model = model;

        using( var sw = new StringWriter() )
        {
            var viewResult = ViewEngines.Engines.FindPartialView( controller.ControllerContext, viewName );
            var viewContext = new ViewContext( controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw );

            viewResult.View.Render( viewContext, sw );
            viewResult.ViewEngine.ReleaseView( controller.ControllerContext, viewResult.View );

            return sw.ToString();
        }
    }
}

あなたのアクションメソッドで:

object model = null; // whatever you want
var obj = new { 
    someOtherProperty = "hello", 
    view = RenderHelper.PartialView( this, "_PartialName", model ) 
};

return Json( obj );

匿名型を返していることに注意してください。レンダリングされたビューの文字列プロパティがある限り、任意の (シリアル化可能な) 型を返すことができます。

テスト

手動レンダリングを使用するアクションをテストするには、わずかな変更が必要です。これは、ビューが MVC パイプラインでレンダリングされるよりも少し前にレンダリングされるためです。

手動レンダリング

  1. アクションメソッドを入力してください
  2. ビューを明示的にレンダリングする <-- これにより、呼び出しアクションのテストが難しくなります
  3. 終了アクション メソッド

自動レンダリング

  1. アクションメソッドを入力してください
  2. ビューの結果を作成する
  3. 終了アクション メソッド
  4. ビューの結果を処理する (ビューをレンダリングする)

つまり、私たちの手動レンダリング プロセスは、テストを困難にする他のさまざまな操作 (ビルド マネージャーと対話してビューをコンパイルするなど) を開始します。

ビューの実際のコンテンツではなく、アクション メソッドをテストしたいと仮定すると、ホストされた環境でコードが実行されているかどうかを確認できます。

    public static string PartialView( Controller controller, string viewName, object model )
    {
        // returns false from a VS 2013 unit test, true from IIS
        if( !HostingEnvironment.IsHosted )
        {
            // return whatever you want here
            return string.Empty;
        }

        // continue as usual
     }

チェックHostingEnvironment.IsHostedは安価です (ボンネットの下では、単純に null チェックです)。

于 2013-09-06T22:49:32.717 に答える
1

<input>ViewModel の JSON 文字列に設定された値を使用して、パーシャルに非表示を作成できます。次に、部分ビューをレンダリングする前に、そのフィールドから JSON 値を取得して解析します。次に、部分ビューからそれを削除し、ページに挿入して、ko.applyBindingsToDescendants(viewModel, $("#parentElement")[0])

このアプローチについて私がどのように感じているかは完全にはわかりません。これは単なる理論です。私はこれをテストしていませんが、うまくいくと思います。注意しなければならない落とし穴の 1 つは、ブラウザーが GET 要求をキャッシュしようとすることです。ajax リクエストでは、次のことを行います。

$.ajax({
  url: "/",
  type: 'GET',
  cache: 'false'
});

または、$.postリクエストを行うだけです。(参考

それが1つのオプションです。

于 2013-09-06T22:42:31.570 に答える