zoukankan      html  css  js  c++  java
  • WebForm下使用 jQuery.loadUserControl异步load用户控件

    现在做网站都追求用户体验,那么ajax自然就必不可少。如果您用过Asp.Net MVC ,你会发现Asp.Net MVC 和jQuery 配合的非常默契(事实上jQuery已经成了微软的御用脚本库了),你可以用jQuery直接去异步加载一个PartialView(即.ascx用户控件)。如:$("#div").load("Controler/UserList.ascx");但是在webForm模式下就没这么幸福了,
    如果你也这样去load一个用户控件,它会报错:"由于已明确禁止所请求的页类型,无法对该类型的页提供服务。扩展名“.ascx”可能不正确。   请检查以下的 URL 并确保其拼写正确"。
    那我们就甘心放弃这样一种让人兴奋的方法,回去像以前那样一句一句的拼接字符串嘛?那样做不仅工作量大,而且繁琐易错,美工给的静态页面也不能拿来直接用,拼字符串时遇到引号还要转义。
    我想,你肯定和我一样都不甘心放弃这种“load”方法,那我们就自己来实现吧。

    首先设想一下,如果有这样一个类,它叫一PageProxy,这个类继承Page类,然后让我们的页面继承这个PageProxy类,而不是像默认的那样继承System.Web.UI.Page,
    使我们在页面上能够直接load用户控件,那么如果我们要在哪个页面上异步load一个用户控件,我们就让那个页面继承这个PageProxy就行了。设想总是美好的,但要我们去实现。

    那我们就去建有这样一个类吧,由于这个类是给其他类继承的,所以有 public abstract class PageProxy : Page。具体代码如下:
       public abstract class PageProxy : Page
        {
            
    /// <summary>
            
    /// 输出用户控件的Html片段
            
    /// </summary>
            
    /// <param name="control">控件的相对路径</param>
            
    /// <returns></returns>
            [WebMethod]
            
    public static string RenderUserControl(string control)
            {
                Page page 
    = new Page();
                UserControl ctl 
    = (UserControl)page.LoadControl("~/" + control);
                page.Controls.Add(ctl);
                StringWriter writer 
    = new StringWriter();
                HttpContext.Current.Server.Execute(page, writer, 
    false);
                
    return writer.ToString();
            }
        }
    这个类只有一个webMethod方法,RenderUserControl,顾名思义,这个方法的功能是输出用户控件,也就是返回用户控件生成的html片断。

    然后让我们的页面继承这个类,如: 
    public partial class WebForm3 : PageProxy

       
    // .......
     }
    这样我们就可以用ajax访问这个方法了。到这里我们可以使用我另一篇文章:甩掉 ashx/asmx,使用jQuery.ajaxWebService请求WebMethod,Ajax处理更加简练中封装的$.ajaxWebService(url, dataMap, fnSuccess)来访问这个方法了。
    假如您已经了解了$.ajaxWebService(url, dataMap, fnSuccess),那现在比如我们要在一个div中加载一个叫UserList.ascx的用户控件:
     $.ajaxWebService("WebForm3/RenderUserControl""{control:'UserList.ascx'}"function(result) {
            $(
    "div").html(result.d);
        });
    到这里我们的工作好像完成了,为什么说好像呢?因为我们还没有直接可以像这样$("div").load("UserList.ascx");简单的加载一个用户控件。
    要实现这样其实也很简单只要给jQuery做个扩展,对上面的代码进行一下封装就OK了。代码如下:
    ///    <summary>
    //
    /    jQuery实例扩展,Ajax加载封装用户控件(*.ascx),输出Html,仅适用于Asp.Net。
    //
    /     依赖 $.ajaxWebService(url, dataMap, fnSuccess)
    //
    /    </summary>
    //
    /    <param name="control" type="String">
    //
    /     需要加载的用户控件的相对路径
    //
    /</param>
    //
    /    <param name="page" type="String">
    //
    /     输出控件Html片段的页面,不一定是当前页面。可选,缺省值为当前页面。
    //
    /</param>
    $.fn.loadUserControl = function(control, page) {
        
    var $dom = this;
        
    if (page == "" || page == null) {
            page 
    = location.pathname.replace("/""");
        }
        page 
    += "/RenderUserControl"//RenderUserControl是PageProxy中的方法,不要轻易修改
        $.ajaxWebService(page, "{control:'" + control + "'}"function(result) {
            $dom.html(result.d);
        });
    }
    其中第一个参数control必选,第二个参数page可选。
    这时我们再加载UserList.ascx,就可以这样写了: $("div").loadUserControl("UserList.ascx");
    这也是我们最终要的效果。


    到此我们的实现就全部完成了。
    下面给出一个完整的示例代码:
           PageProxy.cs:
        public abstract class PageProxy : Page
        {
            [WebMethod]
            
    public static string RenderUserControl(string control)
            {
                Page page 
    = new Page();
                UserControl ctl 
    = (UserControl)page.LoadControl("~/" + control);
                page.Controls.Add(ctl);
                StringWriter writer 
    = new StringWriter();
                HttpContext.Current.Server.Execute(page, writer, 
    false);
                
    return writer.ToString();
            }
        }

     
       WebForm3.aspx.cs:

        public partial class WebForm3 : PageProxy
        {
            
    protected void Page_Load(object sender, EventArgs e)
            {
                
            }
        }
        
    jquery.extend.js:

    //
    /    <summary>
    //
    /    jQuery原型扩展,重新封装Ajax请求WebServeice
    //
    /    </summary>
    //
    /    <param name="url" type="String">
    //
    /     处理请求的地址
    //
    /</param>
    //
    /    <param name="dataMap" type="String">
    //
    /     参数,json格式的字符串
    //
    /</param>
    //
    /    <param name="fnSuccess" type="function">
    //
    /     请求成功后的回调函数
    //
    /</param>
    $.ajaxWebService = function(url, dataMap, fnSuccess) {
        $.ajax({
            type: 
    "POST",
            contentType: 
    "application/json",
            url: url,
            data: dataMap,
            dataType: 
    "json",
            success: fnSuccess
        });
    }




    ///    <summary>
    //
    /    jQuery实例扩展,Ajax加载封装用户控件(*.ascx),输出Html,仅适用于Asp.Net。
    //
    /     依赖 $.ajaxWebService(url, dataMap, fnSuccess)
    //
    /    </summary>
    //
    /    <param name="control" type="String">
    //
    /     需要加载的用户控件的相对路径
    //
    /     </param>
    //
    /    <param name="page" type="String">
    //
    /     输出控件Html片段的页面,不一定是当前页面。可选,缺省值为当前页面。
    //
    /     </param>
    $.fn.loadUserControl = function(control, page) {
        
    var $dom = this;
        
    if (page == "" || page == null) {
            page 
    = location.pathname.replace("/""");
        }
        page 
    += "/RenderUserControl"//RenderUserControl是PageProxy中的方法,不要轻易修改
        $.ajaxWebService(page, "{control:'" + control + "'}"function(result) {
            $dom.html(result.d);
        });

    }

    WebForm3.aspx:

    <%
    @ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="WebFormjQuery.WebForm3" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        
    <title>WebForm下使用jQuery.loadUserControl异步load用户控件</title>
        
    <script src="Scripts/jquery-1.3.2.js" type="text/javascript"></script>
        
    <script src="Scripts/jquery.extend.js" type="text/javascript"></script>
        
    <script type="text/javascript">
            
    function loadUserList(){
             $(
    "#div_userList").loadUserControl("Controls/UserList.ascx");
            }        
        
    </script>
    </head>
    <body>
        
    <form id="form1" runat="server">
        
    <div>
        
    <div><input type="button" value="加载用户列表(用户控件)" onclick ="loadUserList()" /></div>
        
    <div id='div_userList'></div>
        
    </div>
        
    </form>
    </body>
    </html>

    PersonOM:

        public class PersonOM//model类,作为demo,我们就懒得建数据库了
        {
            
    public string Name { getset; }

            
    public int Age { getset; }
        }
    UserList.ascx://待加载的用户控件

        
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UserList.ascx.cs" Inherits="WebFormjQuery.Controls.UserList" EnableViewState="false" %>
        
    <%@ Import Namespace=" System.Collections.Generic" %>
            
    <ul>
                
    <% List<PersonOM> lstps = WebForm1.GetResult(); %>
                
    <% foreach ( PersonOM ps in lstps)
                   { 
    %>
                
    <li>姓名:<%=ps.Name %>&nbsp;&nbsp;年龄:<%=ps.Age %></li>
                
    <%%>
            
    </ul>


      源码下载

    原文地址:http://www.cnblogs.com/xumingxiang/archive/2010/05/04/1727614.html

    作者 : 徐明祥
    出处:http://www.cnblogs.com/xumingxiang 
    版权:本文版权归作者和博客园共有
    转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
    要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
  • 相关阅读:
    vue脚手架搭建项目
    springmvc上传下载文件
    vue双向绑定(模型变化,视图变化,反之亦然)
    android中广告轮播图总结
    studio插件
    系统图片uri的问题
    android
    mysql 外键(FOREIGN KEY)使用介绍
    不用加减乘除来做加法的题目
    Comparable接口实现和使用方法介绍
  • 原文地址:https://www.cnblogs.com/xumingxiang/p/1727614.html
Copyright © 2011-2022 走看看