2012-05-04 36 views
6

Tengo una aplicación MVC que estoy usando varios JsonResult puntos finales para rellenar el javascript ViewModel.MVC pase JSON ViewModel a la vista

He estado utilizando varias solicitudes jQuery Ajax para completar el modelo, pero me gustaría que gran parte del modelo inicial se pase a la vista en el servidor.

El modelo de vista tiene 3-5 piezas (dependiendo de dónde está el usuario en la aplicación):

  1. página enlaza básicos, éstos no cambian muy a menudo y podría ser exactamente el mismo en todo el usuario de sesión
  2. Notificaciones de usuario.
  3. Datos del usuario.
  4. (opcional) de datos que pueden verse en
  5. datos
  6. (opcional) misceláneos

Actualmente estoy usando el código para cargar los primeros tres piezas:

$(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 
    }); 
}; 

He intentado hacer algo como esto, pero estoy descubriendo que al usar el @Html.Action("HomeViewModelJson", "Home") está causando que los encabezados HTTP cambien y que toda la página se envíe como si fuera 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")'); 

Lo que me gustaría hacer es utilizar los puntos finales existentes JsonResult para obtener datos Json en mi ViewModel en el servidor, antes de que la página se envíe al usuario.

¿Hay alguna opción que me permita hacer eso sin reescribir mis controladores?

Respuesta

9

Al renderizar la vista principal está utilizando un modelo de visualización, ¿no? En este modelo de vista simplemente rellenar las propiedades que no desee ser traída con AJAX antes de volver la vista:

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

por ejemplo, si usted tiene la siguiente acción que se utiliza para las peticiones AJAX:

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

se podría utilizar de la acción principal para poblar las propiedades individuales:

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

y luego dentro de la vista correspondiente que podría utilizar el Json.Encode Método para serializar todo el modelo en una cadena JSON:

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

o también podría serializar propiedades individuales si no necesita todos ellos:

@model MyViewModel 
<script type="text/javascript"> 
    var prop1 = @Html.Raw(Json.Encode(Model.Prop1)); 
</script> 
+0

Eso suena como que podría trabajar! Déjame probarlo :) ¡Ni siquiera sabía que eso fuera posible! –

+0

Se olvidó de aceptar. Funcionó muy bien! –

+0

+1 Agradable ............. – SleepyBoBos