34-Ajax辅助方法

     Ajax是Asynchronous JavaScript and XML的缩写,是目前非常热门的网页开发技术之一,利用Ajax开发技术可以帮助网站减少切换页面的机会、加快网页响应速度、降低网络下载流量,也能让用户经验变得更好,ASP.NET MVC内建了Ajax辅助方法,可以帮助开发人员快速且方便地做到许多Ajax互动效果。

      在开始使用Ajax辅助方法之前,必须要先在页面中载入jQuery以及ASP.NET MVC4项目模板内附的jquery.unobtrusive-ajax.js文件才能正常执行。

      为了让网站载入适当的JavaScript函数库,必须先在Layout页面载入适当的JavaScript文件才行。事实上,在ASP.NET MVC4的Internet模板中已经在_Layout.cshtml页面中加上了jQuery载入,可以开启母版页面的最下方看到以下这段:

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>

      在预设的母版页面中,@Scripts.Render("~/bundles/jquery")就是载入项目里的“Scripts\jquery-1.8.2.js”文件。而Ajax功能并不是每一页都要使用,所以预设并没有载入,可以通过@RenderSection区域来载入jquery.unobtrusive-ajax.js文件。

      如果需要在页面中使用ASP.NET MVC的Ajax辅助方法,那么可以在每个需要使用Ajax辅助方法的页面最下方加上以下这段@section语法:

@section Scripts {
    @Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.js")
}

1.使用Ajax超链接功能

      使用Ajax辅助方法和使用HTML辅助方法非常类似,但Ajax辅助方法会比HTML辅助方法多出一个AjaxOptions类型参数,用来控制Ajax执行时的各种参数,稍后马上会提到这个部分。

      我们先以输出超链接来做比较,在撰写View之前,先在HomeController里面新增一个GetTime动作方法,代码如下:

        public ActionResult GetTime()
        {
            return Content(DateTime.Now.ToString("F"));
        }

      先前学过的Html.ActionLink辅助方法用来输出一个超链接,语法如下:

@Html.ActionLink("取得目前时间", "GetTime")

      这段语法的HTML输出如下:

<a href="/Home/GetTime">取得目前时间</a>

      当这个超链接被点击后,会链接到另一个/Home/GetTime页面,如果希望改用Ajax的方式动态地将/Home/GetTime网页的执行结果回传到目前网页的其中一个div里,那么可以改写成如下方式:

复制代码
@Ajax.ActionLink("取得目前时间","GetTime",new AjaxOptions{UpdateTargetId="now"})

<div id="now"></div>

@section Scripts {
    @Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.js")
}
复制代码

      这段代码的HTML输出如下:

<a data-ajax="true" data-ajax-mode="replace" data-ajax-update='#now" href="/Home/GetTime>取得目前时间</a>

<div id="now"></div>

      当网页开启后,单击“取得目前时间”超链接后,浏览器便会自动取得/Home/GetTime网页的完整内容,并将内容直接填入名为now的div区块里。

      第一次使用Ajax辅助方法可能会觉得@Ajax.ActionLink输出的HTML怎么这么奇怪?连一行JavaScript都没有,只在<a>标签上加了几个data-*属性而已,而且功能竟然都还能正常执行。是的,这是一种JavaScript的撰写风格,称为“Unobtrusive JavaScript”,且ASP.NET MVC 4预设就是使用这种风格来执行各式Ajax功能。     

      这里有一点必须特别说明一下,就是通过Ajax远端取得网页内容的过程。浏览器为了让执行效率提升,会预设通过Ajax取得的网页内容只要Ajax调用网址没有改变,且远端的HTTP没有包含缓存相关标头(Headers),那么浏览器就不会再次发出Ajax请求。以上述Ajax.ActionLink辅助方法输出的结果为例,当第一次点击取得/Home/GetTime时会回传当下的服务器时间,当第二次点击同一个网址,按理说应该看到内容更新才对,但结果却永远无法更新,除非你清空浏览器缓存。
      如果你的Ajax回传的数据必须即时更新,那么,就必须调整你的Action方法定义,新增一个OutputCache属性(Attribute),强迫浏览器不要缓存这一页的请求,范例如下:

        [OutputCache(NoStore=true,Duration=0)]
        public ActionResult GetTime()
        {
            return Content(DateTime.Now.ToString("F"));
        }

2.使用Ajax表单功能

      在上一小节中,Ajax超链接是通过超链接启动Ajax功能,而使用Ajax表单功能也非常类似,例如,以下使用Html.BeginForm的辅助方法:

@using(Html.BeginForm()){

      若改用Ajax辅助方法,可以改成以下语法:

@using(Ajax.BeginForm(new AjaxOptions{ UpdateTargetId="now"})){

      完整代码如下:

@using (Ajax.BeginForm("GetTime",new AjaxOptions { UpdateTargetId = "now" }))
{
    <input type="submit" value="取得当前时间" />
} 

<div id="now"></div>

@section Scripts {
    @Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.js")
}

3.了解AjaxOptions类型

      无论你使用Ajax.ActionLink或Ajax.BeginForm,都需要传入AjaxOptions类型的对象当参数,这个参数将决定ASP.NET MVC的Ajax如何运作。下表所示说明了AjaxOptions各属性所代表的意义。

Ajax属性名称 说明
Confirm 执行Ajax之前会先跳出一个确认对话框
HttpMethod 设定HTTP要求的方法(GET或POST)
InsertionMode

设定通过Ajax辅助方法取回数据时,要如何将数据新增至UpdateTargetId指定的元素中,有以下三种方法。

InsertionMode.Replace:取代UpdateTargetId的内容。(默认)

InsertionMode.InsertBefore:在UpdateTargetId之前插入。

InsertionMode.InsertAfter:在UpdateTargetId之后插入。

LoadingElementId 在Ajax尚未完成所有工作前显示的元素Id值
OnBegin 设定开始时要执行的JavaScript函数名称
OnComplete 设定结束时要执行的JavaScript函数名称
OnFailure 设定失败时要执行的JavaScript函数名称
OnSuccess 设定完成时要执行的JavaScript函数名称
UpdateTargetId 设定回传值要显示在哪一个ID上
Url 设定Ajax表单提交的Url

      当使用OnBegin、OnComplete、OnFailure、OnSuccess这四个属性时,如果指定的函数名称不存在于网页中,就会发生JavaScript错误,初学者很有可能因为这个错误找不到原因而放弃使用内建的Ajax辅助方法。

4.案例:留言管理系统中审核留言的应用

@{
    var ajaxOptions = new AjaxOptions()
    {
        OnSuccess = "SetPassSuccess",
        OnFailure = "SetPassFailure",
        Confirm = "设置留言审核状态为'通过'?",
        HttpMethod = "Post"
    };
  }

@section scripts
{
    @Scripts.Render("~/bundles/jqueryval")
    <script>
        function SetPassSuccess() {
            alert('审核通过');
            location.reload();
        }
        function SetPassFailure(xhr) {
            alert('审核失败(HTTP状态代码:' + xhr.status + ')');
        }</script>
}

@foreach (var item in Model)
{
    <div class="box" style="border-bottom: 1px solid black;">
        <br />
        <b>@Html.DisplayNameFor(model => model.Name):</b>
        @Html.DisplayFor(modelItem => item.Name)&nbsp;&nbsp;&nbsp;&nbsp;
        <b>@Html.DisplayNameFor(model => model.PostTime):</b>
        @Html.DisplayFor(modelItem => item.PostTime)<br />
        <b>@Html.DisplayNameFor(model => model.Content):</b>
        @Html.DisplayFor(modelItem => item.Content)<br />
        <br />

        @Ajax.ActionLink("通过审核", "ConfirmPass", new { id = item.Id }, ajaxOptions)<br />
        <br />
    </div> 
}

       以上为视图代码,控制器代码如下。

public ActionResult ConfirmPass(int id)
        {
            Message message = db.Messages.Find(id);
            message.IsPass = "True";

            db.SaveChanges();

            return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
        }

 

posted @ 2015-11-23 10:33  RunningYY  阅读(626)  评论(3编辑  收藏  举报