• 【ASP.NET MVC 学习笔记】- 15 Unobtrusive Ajax


    本文参考:http://www.cnblogs.com/willick/p/3418517.html

    1、Unobtrusive Ajax允许我们通过 MVC 的 Help mothod 来定义 Ajax 的特性,而不用在 View 中参杂一大段 JavaScript 代码。

    2、在MVC中使用普通Ajax的示例:

    • Index.cshtml:
    @{
        ViewBag.Title = "Index";
    }
    
    <script type="text/javascript">
        function test() {
            $.ajax({
                url: '@Url.Action("GetTestData")',
                type: "POST",
                success: function (result) {
                    $("#lblMsg").text(result.msg);
                }
            });
        }
    </script>
    
    <h2 id="lblMsg"></h2>
    <input type="button" value="测试" onclick="test();" />
    • HomeController:
    public JsonResult GetTestData() 
    {
        return Json(new { msg = "Datetime from server:" + DateTime.Now.ToString("HH:mm:ss") });
    }

       运行程序,点击测试按钮,我们可以看到用 Ajax 从后台取回来的时间:

      

        每次点击测试按钮时间都会刷新。这个地方有一点需要提醒大家,这个例子中 $.ajax() 方法使用的是 POST 请求,如果要使用 GET 请求,Test action 中调用 Json 方法需要设置 JsonRequestBehavior 的值为 AllowGet(默认是 DenyGet)。改成 GET 请求后,多次点击测试按钮,时间不会刷新。这是因为 GET 请求在 ASP.NET 中对于相同的URL请求返回的是缓存中的数据。如下:

    public JsonResult GetTestData() 
    {
        return Json(new { msg = "Datetime from server:" + DateTime.Now.ToString("HH:mm:ss") }, JsonRequestBehavior.AllowGet);
    }

    3、Unobtrusive Ajax 是在 Web 页面使用 JavaScript 的一种通用方式。这个术语没有明确的定义,但它有如下基本的原则:

    • 行为(JavaScript 代码)与 Web 页面的结构(Html 标记)和表现(CSS样式)分离。
    • JavaScript 最佳实现,解决JavaScript语言本身存在的传统问题(如缺乏可扩展性和开发人员编码风格不一致性)。
    • 解决浏览器兼容性问题。

        MVC 开启 Unobtrusive JavaScript 后调用 Ajax.BeginForm 方法生成的代码示例:

    <form action="/People/GetPeopleData" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#tableBody" id="form0" method="post">

        这段代码和 JavaScript 是完全分离的,Html标签通过一些标记来告诉 JavaScript 所具有什么样的行为。分离出来的 JavaScript 文件(MVC中指引入的jquery.unobtrusive-ajax.min.js文件)中的代码,没有一句是专门为某个特定的Web页面中的某个Html元素来编写的,即所有函数都是通用的。这就是 Unobtrusive Ajax 的核心思想。

        相对于普通使用 Ajax 的方式,Unobtrusive Ajax 更容易阅读,增强了可扩展性和一致性,而且方便维护。

    4、在 MVC 中使用 Unobtrusive Ajax ,首先要将其“开启”,需要做两个动作。一个是配置根目录下的 Web.config 文件,在 configuration/appSettings 节点下的 UnobtrusiveJavaScriptEnabled 值设为 true,如下所示:

    <configuration> 
        <appSettings><add key="UnobtrusiveJavaScriptEnabled" value="true" /> //默认是开启的
        </appSettings> 
    </configuration> 

        第二个动作就是在需要使用 MVC Unobtrusive Ajax 的 View 中引入jquery库和jquery.unobtrusive-ajax.min.js文件,一般更为常见的是在 /Views/Shared/_Layout.cshtml 中引入,如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
        <script src="~/Scripts/jquery-1.8.2.min.js"></script>
        <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
    </head>
    <body>
        @RenderBody()
    </body>
    </html>

        使用示例:

    //1、创建Model对象
    public class Person 
    {
         public string ID { get; set; }
         public string Name { get; set; }
         public Role Role { get; set; }
    }
    
    public enum Role 
    {
          Admin, User, Guest
    }
    
    //2、创建Controller、Action
    public class PeopleController : Controller 
    {
            private Person[] personData = 
            { 
                new Person {ID = "ZhangSan", Name = "张三", Role = Role.Admin}, 
                new Person {ID = "LiSi", Name = "李四", Role = Role.User}, 
                new Person {ID = "WangWu", Name = "王五", Role = Role.User}, 
                new Person {ID = "MaLiu", Name = "马六", Role = Role.Guest}
            };
    
            public ActionResult Index() 
            {
                return View();
            }
    
            public PartialViewResult GetPeopleData(string selectedRole = "All") 
             {
                IEnumerable<Person> data = personData;
                if (selectedRole != "All") 
                {
                    Role selected = (Role)Enum.Parse(typeof(Role), selectedRole);
                    data = personData.Where(p => p.Role == selected);
                }
                return PartialView(data);
            }
    
            public ActionResult GetPeople(string selectedRole = "All")
            {
                return View((object)selectedRole);
            }
        }
    }
    
    //3、创建Partial View GetPeopleData.cshtml
    @using MvcApplication1.Models
    @model IEnumerable<Person>
    
    @foreach (Person p in Model) {
        <tr>
            <td>@p.ID</td>
            <td>@p.Name</td>
            <td>@p.Role</td>
        </tr>
    }
    
    //4、创建主View GetPeople.cshtml
    @using MvcApplication1.Models
    @model string
    
    @{
        ViewBag.Title = "GetPeople";
        AjaxOptions ajaxOpts = new AjaxOptions {
            UpdateTargetId = "tableBody"
        };
    }
    
    <h2>Get People</h2>
    <table>
        <thead><tr><th>First</th><th>Last</th><th>Role</th></tr></thead>
        <tbody id="tableBody">
            @Html.Action("GetPeopleData", new { selectedRole = Model })
        </tbody>
    </table>
    @using (Ajax.BeginForm("GetPeopleData", ajaxOpts)) {
        <div>
            @Html.DropDownList("selectedRole", new SelectList(
                new[] { "All" }.Concat(Enum.GetNames(typeof(Role)))))
            <button type="submit">Submit</button>
        </div>
    }

        Ajax.BeginForm 是通过提交表单的方式向服务器发送 ajax 请求,MVC中也可以使用 Ajax.ActionLink() 方法生成链接来向服务器发送 ajax 请求。示例:

    <div> 
        @foreach (string role in Enum.GetNames(typeof(Role))) 
        { 
            @Ajax.ActionLink(role, "GetPeopleData",  new {selectedRole = role}, new AjaxOptions {UpdateTargetId = "tableBody"}) @:&nbsp;
        } 
    </div>

        效果图:

      

       当调用 Ajax.BeginForm 方法后,通过 AjaxOptions 对象设置的属性将会被转化成 form 元素的属性(标记),这些属性以 data-ajax 开头,如本示例生成的 form 元素:

    <form action="/People/GetPeopleData" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#tableBody" id="form0" method="post">

       当 GetPeople.cshtml 视图加载完成并呈现 Html 页面时,jquery.unobtrusive-ajax.js 库寻找所有 data-ajax 属性值为true的元素,然后根据其他以 data-ajax 开头的属性值,jQuery 库中的函数将知道如何去执行 Ajax 请求。

    5、AjaxOptions 类中的属性告诉 MVC 框架如何生成 Ajax 请求相关的 JavaScript 和 Html 代码。它包含如下属性:

      

    6、AjaxOptions.Url 属性:在 Ajax.BeginForm() 方中指定了 action 名称参数,MVC 帮我们生成了Ajax请求的Url ( action="/People/GetPeopleData" )。这样做存在一个问题,当浏览器禁用JavaScript的时候,点击提交按钮页面将发生新的请求(非Ajax请求 /People/GetPeopleData),这样服务器返回的数据将直接替换掉原来的页面。解决这个问题可以使用 AjaxOptions.Url 属性,原因是 AjaxOptions.Url 属性会生成另外一个专门用于 ajax 请求的Url。如下我们对 /Views/People/GetPeople.cshtml 进行简单的修改:

    @{
        ViewBag.Title = "GetPeople";
        AjaxOptions ajaxOpts = new AjaxOptions {
            UpdateTargetId = "tableBody",
            Url = Url.Action("GetPeopleData")
        };
    }
    ...
    @using (Ajax.BeginForm(ajaxOpts)) {
        ...
    }

        运行后我们看到的是和先前一样的结果,说明在效果上没有区别。但它生成的 form 属性却不一样:

    <form id="form0" action="/People/GetPeople" method="post" data-ajax-url="/People/GetPeopleData" data-ajax-update="#tableBody" data-ajax-mode="replace" data-ajax="true"> 

        它生成了两个 Url,分别为 action 属性 和 data-ajax-url 属性的值,前者是 Ajax.BeginForm() 方法根据当前 controller 和 action 名称生成的,后者是 AjaxOptions 的 Url 属性生成的。当浏览器没有禁用 JavaScript 时,Unobtrusive Ajax JS库会获取 data-ajax-url 属性的值作为 Url 发生 ajax 请求。当浏览器禁用了 JavaScript 时,自然 action 属性的值决定了表示提交的 Url,服务器将返回原来整个的页面。虽然局部未能刷新,但不会让用户觉得网站做得很糟糕。

    7、当加载数据需要花较长时间,为了避免假死状态,应当给用户一个反馈信息,如“正在加载...”字样。在 MVC 的 Unobtrusive Ajax 中通过 AjaxOptions 的 LoadingElementId 和 LoadingElementDuration 两个属性可轻松做到这一点。修改 GetPeople.cshtml 如下:

    @using MvcApplication1.Models
    @model string
    
    @{
        ViewBag.Title = "GetPeople";
        AjaxOptions ajaxOpts = new AjaxOptions {
            UpdateTargetId = "tableBody",
            Url = Url.Action("GetPeopleData"),
            LoadingElementId = "loading",
            LoadingElementDuration = 1000,
        };
    }
    <h2>Get People</h2>
    <div id="loading" class="load" style="display:none">
        <p>Loading Data...</p>
    </div>

    8、使用MVC中的 Unobtrusive Ajax 弹出确认对话框也很方便,设置一下 AjaxOptions.Confirm 属性的值却可,如下:

    @{
        ViewBag.Title = "GetPeople";
        AjaxOptions ajaxOpts = new AjaxOptions {
            UpdateTargetId = "tableBody",
            Url = Url.Action("GetPeopleData"),
            LoadingElementId = "loading",
            LoadingElementDuration = 1000,
            Confirm = "Do you wish to request new data?" 
        };
    }

    9、AjaxOptions 类中的 OnBegin、OnComplete、OnFailure 和 OnSuccess 属性允许我们在 ajax 请求周期的某个状态点定义回调函数。示例在 GetPeople.cshtml 文件中加入如下4个回调函数:

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

        接着设置 AjaxOptions 对象的4个事件属性:

    @{
        ViewBag.Title = "GetPeople";
        AjaxOptions ajaxOpts = new AjaxOptions {
            UpdateTargetId = "tableBody",
            Url = Url.Action("GetPeopleData"),
            OnBegin = "OnBegin", 
            OnFailure = "OnFailure", 
            OnSuccess = "OnSuccess", 
            OnComplete = "OnComplete"
        };
    }
  • 相关阅读:
    P3373 线段树模板
    由AC自动机引发的灵感
    瞎子摸象序
    Outer Join的where条件
    将 转移单 自动发货
    获取某个结点的所有层
    瞎子摸象库存篇
    js修改select列表选项中的值
    JS仿flash动态切换(横向,带分页器控制,自动正反向循环轮播)
    js操作select下拉列表的一些通用代码
  • 原文地址:https://www.cnblogs.com/wangwust/p/6388965.html
Copyright © 2020-2023  润新知