【问题标题】:MVC pass JSON ViewModel to ViewMVC 将 JSON ViewModel 传递给 View
【发布时间】:2012-05-13 14:06:26
【问题描述】:

我有一个 MVC 应用程序,我正在使用各种 JsonResult 端点来填充 javascript ViewModel。

我一直在使用几个 jQuery Ajax 请求来填充模型,但我希望将尽可能多的初始模型传递给服务器上的视图。

ViewModel 有 3-5 个部分(取决于用户在应用程序中的位置):

  1. 基本页面链接,这些链接不会经常更改,并且在整个用户会话期间可能完全相同
  2. 用户通知。
  3. 用户数据。
  4. (可选)可视数据
  5. (可选)杂项数据

我目前正在使用此代码来加载前三个部分:

$(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 端点将 Json 数据获取到服务器端的 ViewModel 中。

是否有任何选项可以让我在不重写控制器的情况下做到这一点?

【问题讨论】:

    标签: asp.net-mvc-3 knockout.js jsonp viewmodel


    【解决方案1】:

    在渲染主视图时,您使用的是视图模型,对吗?在此视图模型中,只需在返回视图之前填充您不希望使用 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>
    

    【讨论】:

    • 这听起来可能行得通!让我试试看:)我什至不知道这是可能的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 2013-07-14
    • 1970-01-01
    相关资源
    最近更新 更多