1

現在、私は自分のアプリケーションで次のようなことをしています:

// Foo Controller
public ActionResult Details(int id)
{
    ViewBag.id = id;
    return View();
}

// Foo Details View
<script type="text/javascript">
    var viewBag = {
        'id': @ViewBag.id
    };// *Note: MVC will cry about a syntax error here, everything's ok though
</script>
<script type="text/javascript" src="@Url.Content("~/Views/Foo/details.js")"></script>

// details.js
$(function(){
    var jqXHR = $.ajax({
        'url': '/api/foo/getData/' + viewBag.id,
        'type': 'GET'
    });
    jqXHR.done(function(data){
        ...do stuff with data object...
    });
});

// Foo Api Controller
// Instantiates the data class object to be serialized and returned

これを行うのは、<javascript>要素内でオブジェクトの巨大な JSON 文字列をここにぶら下げたくないからです。理想的には、Foo コントローラーを 1 回呼び出して、データ クラス オブジェクトをインスタンス化し、それを JSON 文字列にシリアル化し、それを ViewBag.dataModel などに割り当てたいと考えています。

もちろん@ViewBag、サーバー側のオブジェクトであるため、.js ファイル内にはアクセスできません。これをやや不必要に行ったり来たりするのではなく、これを行うためのよりきちんとした方法を知っている人はいますか?

get1 つの考えは、パラメーターの URL を解析することでしたが、ルート構造によっては潜在的に醜くなる可能性があり、js スクリプトがすべてを実行するためにビューの最初の部分を待つ必要があり、最終的にはそうする必要があります。とにかくその2番目の電話をかけます。

可能かどうかはわかりませんが、ビューの作成中にjs ViewBagとして機能する.jsファイルを動的に生成し、details.jsファイルが読み込まれる前にページに追加してから、その方法でアクセスできますか?または、details.js ファイルをその場で変更することもできます (縮小/バンドルが必要な場合、これは理想的ではない可能性があります)。

望ましい結果は、knockoutJS を使用しており、渡そうとしている最初のオブジェクトは、使用したいサーバーからのすべての初期データを含むページにバインドしたい ViewModel です。サーバーから取得しているデータ オブジェクトは ViewModel であり、これをオブザーバブルにマップして DOM にバインドします。私が使用している現在の方法は問題なく機能しているようで、オーバーヘッドもあまりないようですが、ページの初期ロード時にサーバーへの 2 回目の呼び出しを回避できれば理想的です。

4

1 に答える 1

1

まず、動的な情報をスクリプト タグに書き込みません。代わりに、データを JSON としてエンコードしてから、隠しフィールドに書き込みます。

MVC4 を使用しているため、既に JSON.NET への参照があるため、これを実行できるはずです。

コントローラーで

public ActionResult Details(int id)
{
    var myModel = GetMyModelData(id);
    string modelJson = JsonConvert.SerializeObject(product); 
    return View(modelJson);
}

ビューで

<input type="hidden" id="model" value="@Model" />

JavaScriptで

var modelJson = $('#model').val();
var modelObj = JSON.parse(modelJson);
于 2013-03-09T02:28:06.863 に答える