• GetCallbackEventReference方法实现局部刷新(转)


    实例:页面无刷新加载外部文件,并显示内容。
    新建一个页面,页面代码如下:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <style type="text/css">
            #div_content
            {
               80%;
               height:auto;
               margin:10px auto 10px auto;
            }
        </style>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <dl>
                <dd>
                    <input id="Button1" type="button" value="点击这里,无刷新显示文章内容"/>
                </dd>
            </dl>
            <div id="div_content">
            </div>
        </div>
        </form>
    </body>
    </html>

    打开页面对应的CS文件,显示实现ICallbackEventHandler接口(代码如下):
    public partial class JsCallTest : System.Web.UI.Page,ICallbackEventHandler
    {
        private string result;
        #region ICallbackEventHandler 成员
        string ICallbackEventHandler.GetCallbackResult()
        {
            return result;
        }
        void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
        {
            result =LoadHTML("Article/20110509154200.htm");
        }
    #endregion
    }


    给该类添加几个简单的加载处理外部文件的方法
        /// <summary>
        /// 加载外部文件,获取内容
        /// </summary>
        /// <param name="Path"></param>
        /// <returns></returns>
        public string LoadHTML(string Path)
        {
            System.Text.Encoding encoding = System.Text.Encoding.GetEncoding("gb2312");
            StreamReader sr = new StreamReader(Server.MapPath("~/") + Path, encoding);
            string str = "";
            while (sr.Peek() != -1)
            {
                char[] buffer = new char[4096];
                int bufferFillSize = sr.ReadBlock(buffer, 0, 4096);
                str = str + new string(buffer);
            }
            sr.Close();
            string strResult = findUsedFromHtml(str, Path);
            return strResult;
        }
        /// <summary>
        /// 获取html的内容部分
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        private string findUsedFromHtml(string strHtml, string strFileName)
        {
            string strBody;
            int bodyStart = strHtml.IndexOf("<body");
            int bodyEnd = strHtml.IndexOf("</body>");
            //html开始到<body>前部分
            ViewState["strTop"] = strHtml.Substring(0, bodyStart);
            // Body部分
            strBody = strHtml.Substring(bodyStart, bodyEnd - bodyStart + 7);
            // Body部分后到html结尾部分
            ViewState["strBottom"] = strHtml.Substring(bodyEnd, strHtml.Length - bodyEnd);
            //替换图片地址
            string fullName = strFileName.Substring(strFileName.LastIndexOf("\\") + 1);
            string strOld = fullName.Replace("htm", "files");
            string strTemp = strFileName.Replace("htm", "files"); ;
            string strNew = ResolveUrl("~/" + strTemp);
            strBody = strBody.Replace(strOld, strNew);
            return strBody;
        }
    给前台页面添加一个处理函数:
       <script language="javascript" type="text/javascript">
            function CallService(content) {
                content.innerHTML = "加载中......";
                <%= ClientScript.GetCallbackEventReference(this,"","ReviceService","content")%>
                function ReviceService(result,content){
                    content.innerHTML=result;
                }
            }
      </script>
    给前台页面的input 添加调用:onclick="CallService(div_content)"

     

     

     

     

     

     

     

     

    1.为HTML客户端控件增加回发功能

    一般页面中的按钮并不都是type=submit类型的,大部分是type=button类型的按钮,把type=submit修改成type=button,修改后的代码如下:

    output.Write("<INPUT TYPE=button name=" + this.UniqueID + " Value='[使用提交按钮]' />");

    由于此代码段中的按钮的type属性由sumbit改成了一般按钮类型button,则此按钮输出后将不再具有回发到服务端的功能。

    为了使一般按钮也具有回发的功能,ASP.NET提供了Page.ClientScript.GetPostBackEventReference方法。

    ClientScript类型为ClientScriptManager,该类主要功能是在Web应用程序中定义用于管理客户端脚本的方法。GetPostBackEvent Reference方法体结构如下:

    GetCallbackEventReference(String, String, String, String, String, Boolean) 

    此方法功能是获取一个对客户端函数的引用;调用该方法时,将启动一个对服务器事件的客户端回调。

    此重载方法的客户端函数包含指定的目标、参数、客户端脚本、上下文、错误处理程序和布尔值。

    在期望不执行回发而从客户端运行服务器代码的情况下,可以使用ClientScriptManager类来调用客户端回调。这称为对服务器执行带外回调。

    在客户端回调中,客户端脚本函数向ASP.NET网页发送异步请求。网页修改其正常生命周期来处理回调

    使用GetCallbackEventReference方法对上面代码增加回调客户端功能,修正后的代码如下:

    output.Write("<INPUT type=button name=\"{0}\" 
    value='[使用Page.ClientScript对象方法]' onclick=\"{1}\">",
    this.UniqueID, Page.ClientScript.GetPostBackEvent Reference(this, ""));

    Page.ClientScript.GetPostBackEventReference方法参数介绍:

    第一个参数传递当前控件引用,在实际应用中可以传递任意控件引用,包括子控件;

    第二个参数为可选的命令参数,这里设置为null,一般同时处理多个按钮时可以设置该参数为不同的命令名称。

    转入正题,在代码中增加按钮的onclick单击事件,当单击按钮时会调用GetPostBackEvent Reference方法返回的一串客户端脚本,并且在页面中生成一个客户端方法和两个type=hidden的隐藏域控件。

    下面是以上代码呈现到客户端的HTML代码:

    <INPUT type=button name="PostBackFromClientControl1"value='
    [使用Page. ClientScript对象方法]'onclick="__
    doPostBack('PostBackFromClientControl1','')">
    <div>
    <input type="hidden" name="__EVENTTARGET"
    id="__EVENTTARGET" value="" />
    <input type="hidden" name="__EVENTARGUMENT"
    id="__EVENTARGUMENT" value="" />
    </div>
    <script type="text/javascript">
    //<![CDATA[
    var theForm = document.forms['form1'];
    if (!theForm) {
    theForm = document.form1;
    }
    function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
    theForm.__EVENTTARGET.value = eventTarget;
    theForm.__EVENTARGUMENT.value = eventArgument;
    theForm.submit();
    }
    }
    //]]>
    </script>

    从上面最终输出的HTML源代码可以看到,Button控件的单击事件会执行一个名为_doPostBack的方法,并且此方法也是自动生成在页面中的。在_doPostBack方法中把事件目标对象eventTarget(调用GetPostBackEventReference方法时传递的第一个参数,为当前控件)赋值给当前Form对象,把事件参数对象eventArgument(调用GetPostBackEventReference方法时传递的第二个参数),最后调用Form对象的提交方法,提交窗体,到这里就实现了我们想要的回发功能。

    还要注意到以下两句自动生成的代码:

    <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
    <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />

    这是两个隐藏域类型控件,主要用来存储事件目标对象和事件参数对象的值。还有,在以上的script标记之间,有个嵌套的//<![CDATA[ //]]> 子句,该句与纯控件开发技术无关。该句的功能是通知HTML读取器下面这段不是HTML的内容,需要按附加的转义字符分开保存,以防代码解析出错。

    2.为服务端控件生成回发脚本

    Page.ClientScript.GetPostBackEventReference方法还可以为服务端控件生成自己的回发脚本,可以从客户端回发。

    ASP.NET标准的Button服务端控件最终生成的HTML标记无非也是生成一个type=submit类型的控件。

    对于服务端控件也可以设置客户端回发功能。比如在使用Button控件时把UseSubmitBehavior属性设置为false,则禁用按钮的自动提交功能,就可以使用GetPostBackEventReference方法返回Button控件的客户端回发事件脚本,代码如下所示:

    string strPostBackCode = this.Page.ClientScript.GetPostBackEventReference(button1,"edit");

    然后把Button的客户事件与生成的回发事件脚本进行关联:

    this.button1.Attributes["onclick"] = strPostBackCode;

    其他服务端控件也是这样设置的。

     

    GetCallbackEventReference方法介绍

    Page.ClientScript对象还有个非常重要的方法GetCallbackEventReference。

    使用GetCallbackEventReference方法获取一个对客户端函数的引用,当调用该函数时,它将启动一个对服务器端事件的客户端回调,可以支持设置客户端回调方法名称等

    服务器端控件的局部刷新,CallBack2007-08-13 8:02发现了.net2.0原来有套CallBack机制,可以轻松实现服务器控件类似AJAX的效果(实现局部刷新),不过真的是服务器端控件用AJAX的话,效果确乎是没ASP.NET AJAX 好
    Callback与asp.net ajax的UpdatePanel控件内在实现机制都是Ajax
    但采用UpdatePanel控件的页面仍然采用Postback方式与服务器交互,会更新ViewState
    Callback采用xmlhttp(GET方式)或是iframe,这个过程根本没有涉及到页面的 ViewState (还是没有解决服务器端控件的ViewState问题,而且只支持asp.net2.0,还有很多缺陷,个人不推荐使用)

    http://www.cnblogs.com/teddyma/archive/2005/11/28/286196.html 深度解析Asp.Net2.0中的Callback机制
    http://www.cnblogs.com/jailu/archive/2007/06/26/796045.html 体验ASP.NET2.0客户端回调功能(CallBack)
    http://msdn2.microsoft.com/zh-cn/library/system.web.ui.icallbackeventhandler(VS.80).aspx    MSDN


    ●一个完整的回调包含以下几个过程:
    (1)客户端发出callback请求;
    (2)服务器端接收客户端callback请求;GetCallbackEventReference接受
    (3)服务器端处理请求并回发请求给客户端;RaiseCallbackEvent处理,GetCallbackResult返回
    (4)客户端接收服务器的返回结果并更新HTML。


    ●string Page.ClientScript.GetCallbackEventReference(    //获取一个对客户端函数的引用
          string target, //处理客户端callback的服务器控件的名称(实现ICallbackEventHandler接口)
          string argument, //从JS传递给服务器端RaiseCallbackEvent方法的1个参数
          string clientCallback,//接收服务器处理结果的JS函数名。
          string context,//原封不动的传给指定的返回数据处理的JS函数
          string clientErrorCallback,//服务器端事件处理程序出现错误时接收结果的JS函数
          bool useAsync //true同步;false异步
    )

    ●void Page.ClientScript.RegisterClientScriptBlock (    //向Page对象注册客户端脚本
          Type type, //要注册的客户端脚本的类型
          string key,    //要注册的客户端脚本的名称
          string script, //要注册的客户端脚本内容
          bool addScriptTags //指示是否添加脚本标记的布尔值
    )


    1。要使用Callback首先要继承ICallbackEventHandler接口:
         public partial class Callback : Page, ICallbackEventHandler
         或:
         <%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
    2。实现ICallbackEventHandler接口的两个方法
         string GetCallbackResult() //返回一个string类型(只能是string类型)的数据给客户端脚本
          {
           //////
          }
         void RaiseCallbackEvent(string eventArgument) //含一个string类型的传入参数,可用于接收客户端脚本的参数
          {
          ///////
          return "";
          }

    3。处理回调页面的Page类还需负责客户端回调脚本的管理:指明哪个JS函数发送callback请求、哪个JS函数接收数据。
         protected void Page_Load(object sender, EventArgs e)
          {
           if(!IsPostBack)
            {
             string strRefrence = Page.ClientScript.GetCallbackEventReference(this, "arg", "AAA", "context");
            // 这里AAA是callback成功之后,客户端接收结果的JS方法,可以包含两个参数。
            //this表示执行callback的的服务端控件是当前这个Page,当前的Page必须实现ICallbackEventHandler接口
            //arg是传给RaiseCallbackEvent的参数eventArgument的值,可以用自定义格式的字符串。           
            //context参数会被原封不动的传给指定的返回数据处理的JS函数

             string strCallBack = "function BBB(arg, context) {" + strRefrence + "};";

             Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "BBB", strCallBack, true);  ////注册JS函数BBB,BBB触发GetCallbackEventReference
              }
          }

    这样写更好理解点
    <script language="javascript" type="text/javascript">
    function BBB(arg, context)
    {<%= ClientScript.GetCallbackEventReference(this, "arg", "AAA", "context")%>;}
    </script>
    ●前者把JS函数BBB写在了服务器端然后用RegisterClientScriptBlock注册,客户端调用BBB,BB再调用了GetCallbackEventReference
    第2种,BBB直接写在客户端。


    4。客户端代码:客户端脚本则比较简单了,只需要实现接收callback结果的JS方法(这里是AAA)就OK了
    function AAA(valueRES, context)    //valueRES是服务器端处理后的结果
    {
        document.getElementById(elementId1).innerHTML = valueRES;
        document.getElementById(elementId2).innerHTML = context;
    }


    例子:用callback获取服务器端的时间(12和24小时制)
    Default.aspx.cs
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;

    public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
    {
    protected void Page_Load(object sender, EventArgs e)
        {
         if (!IsPostBack)
          {
           string strRefrence = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveDataFromServer", "context");
           string strCallBack = "function CallBackToTheServer(arg, context) {" + strRefrence + "};";
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallBackToTheServer", strCallBack, true); //注册JS函数CallBackToTheServer
              }
          }
    private string strTimeFormat;
    public string GetCallbackResult()
        {
         if (strTimeFormat != "" && strTimeFormat == "12")
           {return DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss(12小时制)");}
          else
           {return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss(24小时制)");}
        }
    public void RaiseCallbackEvent(string eventArgument)
        {
         strTimeFormat = eventArgument;
        }
    }


    Default.aspx
    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
    <!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>CallBack</title>
    <script language="javascript" type="text/javascript">
    function ReceiveDataFromServer(valueReturnFromServer,context)
    {
        document.getElementById("ServerTime").innerHTML = valueReturnFromServer;
        document.getElementById("PIG").innerHTML = context;
    }
      
    function GetServerTime(format)
    {CallBackToTheServer(format, "你是猪");} //调用触发GetCallbackEventReference的CallBackToTheServer函数(写在服务器端的JS函数)
    </script>
    </head>
    <body>
        <form id="form1" runat="server">
         <div>
           <asp:Button ID="btnShow12" runat="server" Text="获取服务器时间(12小时制)" OnClientClick="javascript:GetServerTime(12);return false;" /><br />
           <asp:Button ID="btnShow24" runat="server" Text="获取服务器时间(24小时制)" OnClientClick="javascript:GetServerTime(24);return false;" /><br />
           <br />
           <span id="ServerTime"><%= DateTime.Now.ToString("yyyy-MM-dd HHHH:mm:ss") %></span>不点击则为默认显示
           <span id="PIG"></span>
          </div>
        </form>
    </body>
    </html>

  • 相关阅读:
    python 函数嵌套
    python 函数对象
    python 函数参数
    python 连接MySQL报错及解决方案
    解决 No module named pip
    python 文件处理
    python
    python 元祖
    python 读取域名信息
    ubuntu 配置网卡,DNS, iptables
  • 原文地址:https://www.cnblogs.com/dwfbenben/p/2600115.html
Copyright © 2020-2023  润新知