zoukankan      html  css  js  c++  java
  • Unobtrusive Ajax in Asp.net MVC

         讲述怎么使用Unobtrusive Ajax之前,先看在Asp.net MVC传统情况下怎么来实现一个下拉框联动效果:

         1. 简单的定义一个model:

        public class Appointment
        {
            public string ClientName { getset; }
            [DataType(DataType.Date)]
            public DateTime Date { getset; }
            public bool TermsAccepted { getset; }
        }

         2. controller和action的实现:

         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="Submit" />
        </p>
    }

        AppointmentData.cshtml:

    @using UnobtrusiveAjax.Models
    @model IEnumerable<UnobtrusiveAjax.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>
    }

        最终的效果就是:当切换下拉框的选择项时,Appointment list也对应变化,但是页面是通过postback来刷新数据的。现在想实现Ajax切换效果:

        4. 启用Unobtrusive Ajax脚本了。

        web.config中新增:

              <add key="UnobtrusiveJavaScriptEnabled" value="true"/>。

        然后在页面中引入:

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

        5. 页面中更新form为ajax form:

    @model string
    @{
        ViewBag.Title = "Index";
        AjaxOptions ajaxOptions = new AjaxOptions
                                      {
                                          UpdateTargetId = "tabledata"
                                      };
    }
    <h4>Appointment List</h4>

    @using(Ajax.BeginForm("AppointmentData", ajaxOptions))
    {
        <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="Submit" />
        </p>
    }

    这时候,基本的Ajax效果已经出来了。如果要继续完善美化,可以从AjaxOptions着手。先看AjaxOptions的属性有:Confirm, HttpMethod, InsertionMode, LoadingElementId, LoadingElementDuration, UpdateTargetId, Url,OnBegin, OnComplete, OnFailure, OnSuccess等。详细的可以参考:http://msdn.microsoft.com/en-us/library/system.web.mvc.ajax.ajaxoptions(v=vs.108).aspx。利用这些属性,我们来一个完美的吧:

    @model string
    @{
        ViewBag.Title = "Index";
        AjaxOptions ajaxOptions = new AjaxOptions
                                      {
                                          UpdateTargetId = "tabledata",
                                          Url = Url.Action("AppointmentData"),
                                          LoadingElementId = "loading",
                                          LoadingElementDuration = 2000,
                                          Confirm = "Do you wish to request new data?",
                                          OnBegin = "OnBegin",
                                          
    OnComplete = "OnComplete",
                                          
    OnFailure = "OnFailure",
                                          
    OnSuccess = "OnSuccess"
                                      };
    }
    <h4>Appointment List</h4>
        <script type="text/javascript">
            function OnBegin() {
                alert("This is the OnBegin Callback");
            }
            function OnSuccess(data) {
                alert("This is the OnSuccessCallback: " + data);
            }
            function OnFailure(request, error) {
                alert("This is the OnFailure Callback:" + error);
            }
            function OnComplete(request, status) {
                alert("This is the OnComplete Callback: " + status);
            }
        </script>
    <div id="loading" style="display: none; color: Red; font-weight: bold">
        <p>
            Loading Data...</p>
    </div>
    @using (Ajax.BeginForm(ajaxOptions))
    {
        <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="Submit" />
        </p>
    }

    其中标黄部分是为了兼容不支持js的浏览器(原有实现在不支持js的浏览器中直接返回没有html的原始数据)。

          6. 增加Ajax Links(支持Ajax的超链接)。在index顶部增加:

    @foreach (string str in new[] { "All""Joe""Jane""Bob" })
    {
        <div style="margin-right: 5px; float: left">
                @Ajax.ActionLink(str, "AppointmentData"new { id = str },
                new AjaxOptions
                {
                    UpdateTargetId = "tabledata",
                    LoadingElementId = "loading",
                })
        </div>
    }

    这时,点击它所生成的链接,和切换下拉框选中内容,效果完全一样。

         7. 为了让上一步中ajax兼容不支持js的浏览器,并将ajax response回来的html数据改为json原始数据,做一些改进。

         controller变为:

        public class AppointmentController : Controller
        {
            public ActionResult Index(string id)
            {
                return View("Index", (object)id);
            }

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

                if (Request.IsAjaxRequest())
                {
                    return Json(data.Select(m => new
                                                     {
                                                         ClientName = m.ClientName,
                                                         Date = m.Date.ToShortDateString()
                                                     }),
                                                     JsonRequestBehavior.AllowGet);
                }
                else
                {
                    return View(data);
                }
            }
        }

    标黄部分的变更前者是为了兼容get和post2种请求,后者是为了兼容普通请求和ajax请求并分别生成不同类容。其中,Request.IsAjaxRequest()方法可以判断当前请求是否来自Ajax。

          view变更为:


    @model string
    @{
        ViewBag.Title = "Index";
        AjaxOptions ajaxOptions = new AjaxOptions
                                      {
                                          UpdateTargetId = "tabledata",
                                          //Url = Url.Action("AppointmentData"),
                                          LoadingElementId = "loading",
                                          LoadingElementDuration = 2000,
                                          Confirm = "Do you wish to request new data?",
                                          //OnBegin = "OnBegin",
                                          
    //OnComplete = "OnComplete",
                                          
    //OnFailure = "OnFailure",
                                          
    //OnSuccess = "OnSuccess"
                                      };
    }
    <h4>Appointment List</h4>
    <script type="text/javascript">
        function OnSuccess2(data) {
            var target = $('#tabledata');
            target.empty();
            for (var i = 0; i < data.length; i++) {
                target.append('<tr><td>' + data[i].ClientName + '</td><td>' + data[i].Date + '</td></tr>');
            }
        }
    </script>
    <div id="loading" style="display: none; color: Red; font-weight: bold">
        <p>
            Loading Data...</p>
    </div>
    @using (Ajax.BeginForm(ajaxOptions))
    {
        <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="Submit" />
        </p>
    }
    @foreach (string str in new[] { "All""Joe""Jane""Bob" })
    {
        <div style="margin-right: 5px; float: left">        
            @Ajax.ActionLink(str, "Index"new { id = str }, new AjaxOptions
            {
                Url = Url.Action("AppointmentData"new { id = str }),
                LoadingElementId = "loading",
                LoadingElementDuration = 2000,
                OnSuccess = "OnSuccess2"
            })
        </div>
    }

         8. 原理:

         Browser端查看html源码发现form部分为:

    <form action="/Appointment" data-ajax="true" data-ajax-confirm="Do you wish to request new data?" data-ajax-loading="#loading" data-ajax-loading-duration="2000" data-ajax-mode="replace" data-ajax-update="#tabledata" id="form0" method="post">    

         ajax links部分为:

    <data-ajax="true" data-ajax-loading="#loading" data-ajax-loading-duration="2000" data-ajax-success="OnSuccess2" data-ajax-url="/Appointment/AppointmentData/Bob" href="/Appointment/Index/Bob">Bob</a>

    所以它实际上和validation部分类似,不过是在html中隐藏了很多自定义属性,然后在unobtrusive ajax 的js中去获取,然后根据这些值来分别处理。

          9. 如果禁用了unobtrusive ajax,则mvc framework会自动启用MicrosoftAjax.js和MicrosoftMVCAjax,但是你需要手动引入它们。它们效果相同,但实现原理不一样。

          源码download 

  • 相关阅读:
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    asp.net session对象的持久化
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    小白也能看懂的约瑟夫环问题
  • 原文地址:https://www.cnblogs.com/Langzi127/p/2734836.html
Copyright © 2011-2022 走看看