6

私は、さまざまなJsonResultエンドポイントを使用して javascript ViewModel を設定する MVC アプリケーションを持っています。

モデルを設定するためにいくつかの jQuery Ajax リクエストを使用してきましたが、初期モデルの多くをサーバー上のビューに渡したいと考えています。

ViewModel には 3 ~ 5 個の部分があります (ユーザーがアプリケーション内のどこにいるかによって異なります)。

  1. 基本的なページ リンク。これらは頻繁には変更されず、ユーザーのセッション全体でまったく同じになる可能性があります。
  2. ユーザー通知。
  3. ユーザーデータ。
  4. (オプション) 表示可能なデータ
  5. (オプション) その他のデータ

現在、このコードを使用して最初の 3 つの部分をロードしています。

$(document).ready(function () {

    ko.applyBindings(viewModel);
    @Html.Raw(ViewBag.Script)

    // Piece 1.  Almost always the same thing
    postJSON('@Url.Action("HomeViewModelJson", "Home")', function (data) {

        if (data == null)
            return;

        for (var i in data.Tabs) {
            viewModel.tabs.push({ name: data.Tabs[i] });
        }

        for (var i in data.Buttons) {
            viewModel.metroButtons.push({ name: data.MetroButtons[i] });
        }

        for (var i in data.Ribbons) {
            viewModel.ribbons.push(data.Ribbons[i]);
        }
        ApplyButtonThemes();
    });
});


// Piece 2.  Changes constantly. OK as is
postJSON('@Url.Action("GetNotifications", "NotificationAsync")', function (nots) {
    viewModel.notifications.removeAll();

    ko.utils.arrayForEach(nots, function (item) {
        item.readNotification = function () {
            hub.markNotificationAsRead(this.Id);
            return true;
        };
        viewModel.notifications.push(item);
    });
});

// Piece 3. Changes but should also be loaded at startup
postJSON('@Url.Action("GetUser", "UserAsync")', function (user) {
    viewModel.user(koifyObject(user));
});


postJSON = function(url, data, callback) {
    if($.isFunction(data)) {
        callback = data;
        data = {};
    }
    $.ajax({
        'type': 'POST',
        'url': url,
        'contentType': 'application/json',
        'data': ko.toJSON(data),
        'dataType': 'json',
        'success': callback
    });
};

私はこのようなことを試みましたが、を使用する@Html.Action("HomeViewModelJson", "Home")とHTTPヘッダーが変更され、ページ全体がJSONのように送信されることがわかりました

       (function (data) {

            if (data == null)
                return;

            for (var i in data.Tabs) {
                viewModel.tabs.push({ name: data.Tabs[i] });
            }

            for (var i in data.MetroButtons) {
                viewModel.metroButtons.push({ name: data.MetroButtons[i] });
            }

            for (var i in data.Ribbons) {
                viewModel.ribbons.push(data.Ribbons[i]);
            }
            ApplyMetroButtonThemes();
        })('@Html.Action("HomeViewModelJson", "Home")');

私がやりたいことは、既存のJsonResultエンドポイントを使用して、ページがユーザーに送信される前に、サーバー側の ViewModel に Json データを取得することです。

コントローラーを書き換えずにそれを可能にするオプションはありますか?

4

1 に答える 1

9

メイン ビューをレンダリングするときは、ビュー モデルを使用していますよね? このビュー モデルでは、ビューを返す前に、AJAX で取得したくないプロパティを設定するだけです。

public ActionResult Index()
{
    MyViewModel model = ...
    model.Prop1 = ...
    model.Prop2 = ...
    return View(model);
}

たとえば、AJAX 要求に使用される次のアクションがあるとします。

public JsonResult GetProp1()
{
    Property1ViewModel model = ...
    return Json(model, JsonRequestBehavior.AllowGet);
}

メイン アクションからそれを使用して、個々のプロパティを設定できます。

model.Prop1 = (Property1ViewModel)GetProp1().Data;
model.Prop2 = (Property2ViewModel)GetProp2().Data;

次に、対応するビュー内でJson.Encodeメソッドを使用して、モデル全体を JSON 文字列にシリアル化できます。

@model MyViewModel
<script type="text/javascript">
    var model = @Html.Raw(Json.Encode(Model));
    // You could use model.Prop1 and model.Prop2 here
</script>

または、すべてが必要でない場合は、個々のプロパティをシリアル化することもできます。

@model MyViewModel
<script type="text/javascript">
    var prop1 = @Html.Raw(Json.Encode(Model.Prop1));
</script>
于 2012-05-04T06:08:51.583 に答える