非侵入式Ajax

基本准备  

  首先,新建一个ASP.NET MVC 3的空项目。

  然后新增一个Model,代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MVCApplication.Models
{
    public class Appointment
    {
        public string ClientName { get; set; }

        [DataType(DataType.Date)]
        public DateTime Date { get; set; }

        public bool TermAccepted { get; set; }
    }
}

  接着是新增一个Controller,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCApplication.Models;

namespace MVCApplication.Controllers
{
    public class AppointmentController : Controller
    {
        //
        // GET: /Appointment/

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Index(string id)
        {
            return View("Index", (object)id);
        }

        public ViewResult AppointmentData(string id)
        {
            IEnumerable<Appointment> data = new[] {
                new Appointment{ClientName="Joe", Date = DateTime.Parse("1/1/2012")},
                new Appointment{ClientName="Joe", Date = DateTime.Parse("2/1/2012")},
                new Appointment{ClientName="Joe", Date = DateTime.Parse("3/1/2012")},
                new Appointment{ClientName="Jane", Date = DateTime.Parse("1/20/2012")},
                new Appointment{ClientName="Jane", Date = DateTime.Parse("1/22/2012")},
                new Appointment{ClientName="Bob", Date = DateTime.Parse("2/25/2012")},
                new Appointment{ClientName="Bob", Date = DateTime.Parse("2/25/2013")}
            };

            if(!string.IsNullOrEmpty(id) && id != "All")
            {
                data = data.Where(e => e.ClientName == id);
            }

            return View(data);
        }
    }
}

  最后是新增两个View,分别如下。

  Index.cshtml:

@model string
@{
    ViewBag.Title = "Index";
}

<h4>Appointment List</h4>

@using (Html.BeginForm())
{
    <table>
        <thead>
            <th>Client Name</th>
            <th>Appointment Date</th>
        </thead>
        <tbody id="tabledata">
            @Html.Action("AppointmentData", new { id = Model})
        </tbody>
    </table>
    <p>
        @Html.DropDownList("id", new SelectList(new[] {"All", "Joe", "Jane", "Bob"}, (Model ?? "All")))
        <input type="submit" value="Sumbit" />
    </p>
}

  AppointmentData.cshtml:

@using MVCApplication.Models
@model IEnumerable<MVCApplication.Models.Appointment>
@{
    Layout = null;
}
@foreach (Appointment appt in Model)
{
    <tr>
        <td>@Html.DisplayFor(m => appt.ClientName)</td>
        <td>@Html.DisplayFor(m => appt.Date)</td>
    </tr> 
}

   其中,AppointmentData.cshtml是作为一个partialview的。

  这样,当点击按钮时,页面回送给服务器,根据用户所选择的选项显示相应数据。

启用AJAX

  为了启用AJAX,需要在Web.config中新增一行配置,如下:

<configuration>
  <appSettings>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>
...
</configuration>

  这里有两个配置,第一个是启用客户端验证的,它依赖于第二个配置。第二个配置就是启用AJAX的。

  页面上为了引用AJAX,需要引用一个AJAX文件,可以加在模板页中,如下:

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-Ajax.js")" type="text/javascript"></script>

     接下来还要做两个工作。

  第一,定义一个AjaxOptions,这个里面有很多配置,目前先只使用UpdateTargetId,它定义要替换的目标。

  第二,将Html.BeginForm()替换为Ajax.BeginForm("AppointmentData", ajaxOpts)。

  修改后的Index.cshtml如下:

@model string
@{
    ViewBag.Title = "Index";
    AjaxOptions ajaxOpts = new AjaxOptions
    {
        UpdateTargetId = "tabledata"
    };
}

<h4>Appointment List</h4>

@using (Ajax.BeginForm("AppointmentData", ajaxOpts))
{
    <table>
        <thead>
            <th>Client Name</th>
            <th>Appointment Date</th>
        </thead>
        <tbody id="tabledata">
            @Html.Action("AppointmentData", new { id = Model})
        </tbody>
    </table>
    <p>
        @Html.DropDownList("id", new SelectList(new[] {"All", "Joe", "Jane", "Bob"}, (Model ?? "All")))
        <input type="submit" value="Sumbit" />
    </p>
}

   OK,这样点击按钮时就会在后台发送一个Ajax请求。

实现剖析

   AjaxOptions类会被转换成Html元素,这是Ajax帮助类实现的。比如,我们上面的Ajax.BeginForm()会输出下面的HTML。

<form action="/Appointment/AppointmentData" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#tabledata" id="form0" method="post">

   jquery.unobtrusive-ajax.js会扫描HTML的DOM对象,通过data-ajax="true"识别ajax form。别的data-ajax开头的属性是我们在AjaxOptions中设置的相应属性。

  以上是使用了MVC框架的AJAX支持。你也可以选择不使用这种方式,比如完全使用JQUERY,或者使用别的框架,或者直接使用JS。但是不要在一个View中混合使用以上方式,以免发生冲突而得到意外的结果。

设置AJAX选项

  我们可以通过设置AjaxOptions的属性很好地调整我们的AJAX请求的行为。

优雅切换

  上面的例子中,我们做到了使用Ajax做请求,但这依赖于客户端启用JS。一旦客户端禁用JS,那一切将变得徒劳无功。

  最简单的解决办法是设置AjaxOptions中的Url属性,通过使用Url.Action(action method)方法,同时使用Ajax.BeginForm(AjaxOptions)方法。如果客户端启用JS支持,那么一切仍然是正常的,否则就会Index action会收到Post请求,然后整个页面都会刷新。

原文地址:https://www.cnblogs.com/fxb248/p/3209562.html