1

所以我正在创建一个 asp.NET MVC3 应用程序,并希望将单页应用程序功能应用于应用程序的某些部分。我认为最简单的解释方法是举个例子:

该应用程序由管理区域和公共区域组成,使用普通链接结构构建。我想将管理区域转换为单页应用程序,重用现有应用程序中的视图和模型。是否有可能做到这一点,在这种情况下怎么做?

4

1 回答 1

2

您必须面对两个主要问题,这使得 SPA 和标准应用程序之间存在差异:

  • 链接:在标准应用程序中,每个链接都会将您重定向到不同的页面。
  • 表单:提交表单时,会使用您在帖子中指定的 HTTP 方法(通常是 POST)发出请求,并且它在有效负载中包含用户输入的数据。

为了解决这些问题,您必须在客户端和服务器端都采取行动。为了解释提议,让我们使用以下代码:

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

索引.cshtml:

<p>This is a simple page.</p>
<p>@Html.ActionLink("Click here to contact us", "Contact")

客户端: 我们应该修复页面之间的链接,以及表单提交。

  • 链接:您可以在 JS(如果您愿意,可以使用 jQuery)中连接一个事件,该事件将观察您希望在 SPA 上应用的区域中的每个链接点击 - 然后,而不是重定向用户 - 您将加载通过 AJAX 的内容。例如,看看这个示例:

    $("a").click(function(e) {
        e.preventDefault(); // Disable standard redirecting
        var href = $(e.currentTarget).attr("href");
    
        $.get(href, function(responseText) {
            $("#main-content-wrapper").html(responseText);
        });
    });
    
  • 表单:就像我们用于链接的方法一样,我们可以将观察者连接到 JS 中的表单提交事件,然后使用 AJAX 传输数据。例如:

    $("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. */
                },
        });
    });
    

服务器端: 由于您不希望破坏当前的应用程序逻辑 - 您仍然必须能够使用标准的 ASP.NET MVC 方法 - 例如 View()、Redirect() 等。在这种情况下,我建议创建您自己的自定义控制器基类——它将覆盖 ASP.NET 基本实现。

例如,这是一个起点:

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

您必须记住的几件事:

  • 您必须以某种方式区分标准请求和 AJAX 请求——我使用 Request.IsAjaxRequest() 的方式是一种很好的方式。
  • Many times when you're handling a form, In the form submittion action, after you finish with the form logic, you're using Redirect() to redirect the user to another page. As you may have guessed, you can't take this approch when developing SPA. However, I can think of few solutions for this problem:
    • You can create a status handler in the JS code so when redirecting is been issued by the server - you can load the content via AJAX / display a message and so on.
    • You can override Redirect() and add a specific logic to perform in case of redirection when the request was done by AJAX - for instance, you can request from ASP.NET to perform the action that you're going to be transfered into and then return its content etc.
    • You can decide that although its an SPA app - when a redirect was issued - you allows the server to perform this redirection.

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.)

于 2013-03-30T17:30:00.970 回答