2012-05-04 3 views
6

У меня есть приложение MVC, использующее различные конечные точки JsonResult для заполнения javascript ViewModel.MVC pass JSON 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 на стороне сервера, прежде чем страница будет отправлена ​​пользователю.

Есть ли варианты, которые позволят мне сделать это без переписывания контроллеров?

ответ

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 Ницца ............. – SleepyBoBos

Смежные вопросы