2012-05-04 18 views
6

Ich habe eine MVC-Anwendung, die ich verschiedene JsonResult Endpunkte verwenden, um das Javascript ViewModel zu füllen.MVC übergeben JSON ViewModel anzeigen

Ich habe mehrere jQuery Ajax-Anfragen verwendet, um das Modell zu füllen, aber ich möchte so viel von dem ursprünglichen Modell an die Ansicht auf dem Server übergeben werden.

Das Ansichtsmodell hat 3-5 Stück (je nachdem, wo sich der Benutzer in der Anwendung):

  1. Links-Seite Basis, diese nicht sehr oft ändern und könnte genau das gleiche während des gesamten Benutzers sein Sitzung
  2. Benutzerbenachrichtigungen.
  3. Benutzerdaten.
  4. (optional) Sichtbarer Daten
  5. (optional) misc Daten

ich diesen Code zur Zeit bin mit den ersten drei Stücke zu laden:

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

Ich habe versucht, so etwas wie dies zu tun, aber ich finde, dass durch die Verwendung der @Html.Action("HomeViewModelJson", "Home") bewirkt wird, dass die HTTP-Header geändert werden und die ganze Seite gesendet wird, als wäre es 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")'); 

Ich möchte die vorhandenen JsonResult Endpunkte verwenden, um Json-Daten in mein ViewModel auf der Serverseite zu bekommen, bevor die Seite an den Benutzer gesendet wird.

Gibt es irgendwelche Optionen, die mir erlauben, das zu tun, ohne meine Controller neu zu schreiben?

Antwort

9

Beim Rendern der Hauptansicht verwenden Sie ein Ansichtsmodell, oder? In dieser Ansicht Modell füllt einfach die Eigenschaften, die Sie nicht wollen, vor der Rückkehr in die Ansicht mit AJAX geholt werden:

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

zum Beispiel, wenn Sie die folgenden Aktion, die für die AJAX-Anfragen verwendet wird:

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

Sie es von der Haupt-Aktion verwenden, könnten einzelne Eigenschaften zu füllen:

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

und dann in der entsprechenden Ansicht könnten Sie dieverwendenVerfahren das gesamte Modell in einen JSON-String serialisiert:

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

oder Sie können auch einzelne Eigenschaften serialisiert werden, wenn Sie alle von ihnen nicht brauchen:

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

Das klingt wie es funktionieren könnte! Lass es mich ausprobieren :) Ich wusste nicht einmal, dass das möglich ist! –

+0

Vergessen zu akzeptieren. Hat super funktioniert! –

+0

+1 Schön ............. – SleepyBoBos