Reputation: 25
So I'm creating a asp.NET MVC3 application and want to apply single page application functionality to parts of the application. I think the easiest way to explain is with an example:
The app consists of an admin area and a public area and is built using ordinary link-structure. I want to convert the admin area to an single page application reusing view and models from the existing application. Is it possible to do this and in that case how?
Upvotes: 1
Views: 867
Reputation: 2221
You have to face two main problems, which makes the difference between SPA and standard application:
In order to solve that problems, you have to take action both in client-side and server-side. For explaining propose, lets take the following code:
HomeController.cs:
public class HomeController : Controller {
public ActionResult Index() {
return View();
}
public ActionResult Contact() {
return View(new ContactUsViewModel());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Contact(ContactUsViewModel model) {
if (ModelState.IsValid) {
/* Send mail / Save in DB etc. */
return Redirect("Index");
}
return View(model);
}
}
Index.cshtml:
<p>This is a simple page.</p>
<p>@Html.ActionLink("Click here to contact us", "Contact")
Client-Side: We should fix up linking between pages, as well as forms submittions.
Links: You can wire up an event in JS (jQuery if you'd like) that'll observe for each link click in the areas you'd like to apply on SPA - then, instead of redirecting the user - you'll load the content via AJAX. For instance, take a look at this sample:
$("a").click(function(e) {
e.preventDefault(); // Disable standard redirecting
var href = $(e.currentTarget).attr("href");
$.get(href, function(responseText) {
$("#main-content-wrapper").html(responseText);
});
});
Forms: Just like in the approch we've used for links, we can wire up an observer to the form submit event in JS and then transfer the data using AJAX. For instance:
$("form").submit(function(e) {
e.preventDefault(); // Disable standard submittion
var data = $(e.currentTarget).serialize(); // Serializing the form data
var method = $(e.currentTarget).attr("method");
if (typeof (method) == "undefined") { method = "POST"; }
$.ajax({
method: $(e.currentTarget).attr("method"),
parameters: data,
statusCodes: {
404: function() { /* Handle it somehow */ }
403: function() { /* Handle it... */ }
200: function(response) {
/* Since we've done a form submittion, usurally if we're getting standard OK (200) status code - we've transffered a data - such as JSON data - indicating if the request success or we got errors etc. The code you're writing here depends on how your current application works. */
},
});
});
Server-Side: Since you don't wish to break your current application logic - you have to still be able to use standard ASP.NET MVC methods - such as View(), Redirect() and so on. In this case, I recommend to create your own custom base Controller class - which will override ASP.NET basic implementation.
For instance, this is a starting point:
public class MyController : System.Web.Mvc.Controller {
public override View(string viewName) {
if (Request.IsAjaxRequest()) {
return PartialView(viewName); // If this is an AJAX request, we must return a PartialView.
}
return base.View(viewName);
}
}
Few things you have to keep in mind:
As you can see - there're many approches you can take, and they depends on the way you've developed your site, how you wish it to work and what is the basic rules you're defining (e.g. "No redirection is permitted never - even after submitting a form", "After form submittion - always in case that the operation success - I'm displaying a message or performing other JS action. Because of that, I can override Redirect() and if this is an AJAX request I can return a JSON object." etc.)
Upvotes: 2