2012-05-04 98 views
6

我有一个MVC应用程序,我使用各种JsonResult端点来填充javascript ViewModel。MVC通过JSON ViewModel查看

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

视图模型有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中,然后再将页面发送给用户。

有没有任何选项可以让我做到不重写我的控制器?

回答

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> 
+0

这听起来像它可能工作!让我试试:)我甚至不知道这是可能的! –

+0

忘记接受。工作很棒! –

+0

+1 Nice ............. – SleepyBoBos