zoukankan      html  css  js  c++  java
  • 摘自网络"浅析UpdatePanel的partial render原理"

          在我接触ajax.net前,update panel的大名已经是如雷贯耳了。update panel到底如何实现partial render的呢,半年来一直塞在我的思绪中。
          一个星期前,终于开始了我的ajax.net之旅,美妙绝伦的js 扩展令人陶醉。但不幸的是在我以updatepanel machinism,inside updatepanel ajax等等等为关键字 google,baidu后依然没有任何斩获,大多数搜到的条目都是告诉你如何往updatepanel里面拖控件的。我也知道博客园众多高人,其中老赵同志最为显目,我翻了他的很多文章,都没能打开我的心结。(可能他写过相关文章,我没找到。)
         没办法,只好用reflector打开程序集,我努力的寻找,寻找那个方法,那个能改变呈现流程的方法。终于我找到了你  ----------- SetRenderMethodDelegate。
          以下代码模拟了update panel的partial render行为。
     ParialRender.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;
    using System.Collections.Specialized;

    public partial class PartialRender : System.Web.UI.Page
    {
        
    private static Random random = new Random();

        
    protected void Page_Load(object sender, EventArgs e)
        
    {
            NameValueCollection headers 
    = this.Request.Headers;
            
    // 识别异步回调
            if(headers["x-myajax"!= null)
            
    {
                
    this.SetRenderMethodDelegate(this.MyAjaxPageRender);
                
    this.form1.SetRenderMethodDelegate(this.MyAjaxFormRender);
            }

        }


        
    // 改变页面的呈现流程
        private void MyAjaxPageRender(HtmlTextWriter writer, Control page)
        
    {
            
    this.form1.RenderControl(writer);
        }


        
    // 改变form的呈现流程
        private void MyAjaxFormRender(HtmlTextWriter writer, Control page)
        
    {
            
    this.UpdatePanel.RenderControl(writer);
        }


        
    protected void btnSubmit_Click(object sender, EventArgs e)
        
    {
            
    this.txtRandomNumber.Text = random.Next(1000).ToString();
        }

    }


    PartialRender.aspx


    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="PartialRender.aspx.cs" Inherits="PartialRender" %>

    <!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>浅析update panel 之 partial render 原理</title>
        
    <script>
        
    var xmlHttp;
        
        
    // 创建xmlhttprequest对象
        function createXMLHttpRequest() {
            
    if (window.ActiveXObject)
            
    {
                
    return new ActiveXObject("Microsoft.XMLHTTP");
            }

            
    else if (window.XMLHttpRequest) {
                
    return new XMLHttpRequest();
            }

            
    else {
                
    return null;
            }

        }

        
        
    // 状态改变handle
        function handleStateChange() {
            
    if (xmlHttp.readyState == 4{
                
    if (xmlHttp.status == 200{
                    processCallback();
                }

            }

        }

        
        
    // 处理异步回调
        function processCallback() {
            parseDom(xmlHttp.responseText);
        }

        
        
    // 发出异步请求
        function doRequest() {
            xmlHttp 
    = createXMLHttpRequest();
            
    var url = window.location.href;
            xmlHttp.open(
    "POST", url, true);
            xmlHttp.onreadystatechange 
    = handleStateChange;
            
    // 标记异步回调
            xmlHttp.setRequestHeader("x-myajax""nothing");
            xmlHttp.setRequestHeader(
    "Content-Type""application/x-www-form-urlencoded;"); 
            
    var queryString = createQueryString();
            xmlHttp.send(queryString);
        }

        
        
    // 创建 querystring ,也就是模拟表单里面的name-value对。
        function createQueryString() {
            
    var result = "btnSubmit=";
            result 
    += "&txtRandomNumber=" + document.getElementById("txtRandomNumber").value;
            parseDom(document.forms[
    0].outerHTML);
            
    for (var i = 0; i < hiddenFields.length / 2; i++)
            
    {
                
    var hiddenField = document.getElementById(hiddenFields[i * 2]);
                result 
    += "&" + encodeURIComponent(hiddenField.name) + "=" + encodeURIComponent(hiddenField.value);
            }

            
    return result;
        }

        
        
    // 这里存放隐藏字段的id 和 value,隐藏字段就是__VIEWSTATE之类的东西
        var hiddenFields = null;
        
    // updatePanel 内部的html
        var updatePanelContent = null;
        
        
    // 分析一段html,求出它里面 <input type=hidden> 和 update panel
        function parseDom(text) {
            hiddenFields 
    = [];
            updatePanelContent 
    = "";
            
    var root = document.createElement("span");
            root.innerHTML 
    = text;
            parseNode(root);
            
    for (var i = 0; i < hiddenFields.length / 2; i++{
                document.getElementById(hiddenFields[i 
    * 2]).value = hiddenFields[i * 2 + 1];
            }
     
            document.getElementById(
    "UpdatePanel").innerHTML = updatePanelContent;
        }

        
        
    // 递归分析节点
        function parseNode(node) {
            
    if (node.nodeType == 3){
                
    return;
            }

            
    if (node.tagName.toLowerCase() == "input" && node.type.toLowerCase()  == "hidden"{
                hiddenFields.push(node.id);
                hiddenFields.push(node.value);
                
    return;
            }

            
    if (node.id == "UpdatePanel"{
                updatePanelContent 
    = node.innerHTML;
                
    return;
            }

            
    for (var i = 0; i < node.childNodes.length; i++{
                parseNode(node.childNodes[i]);
            }

        }

        
        
    </script>
    </head>
    <body>
        
    <form id="form1" runat="server">
         
    <asp:Panel ID="UpdatePanel" runat="server" >
                
    <asp:Button ID="btnSubmit" runat="server" Text="生成随机数" OnClick="btnSubmit_Click" OnClientClick="doRequest();return false;"  />
                
    <asp:TextBox ID="txtRandomNumber" runat="server"></asp:TextBox>
         
    </asp:Panel>
        
    </form>
    </body>
    </html>
    代码在普通的panel中放了一个button,一个textbox,按button就能无刷新的产生随机数。
    1.要改变submit的行为,原来的表单不能提交了,而是交给xmlhttprequest提交。
    2.服务器端要知道是xmlhttprequest做的请求还是普通的请求,这个通过设置一个自定义的http头实现 x-myajax.
    3.要改变服务器端的呈现流程,原来呈现整个页面,但异步请求的时候只能
    呈现updatepanel和一些系统级别的东西(__VIEWSTATE之类).我们通过Control的SetRenderMethodDelegate方法来实现。
    4.要能解析response text, 根据解析的结果设置__VIEWSTATE 的值,设置updatepanel内部的html。
    这只是一个简单的模拟,实际中updatepanel,scriptmanager的行为复杂得多,比如说trigger,focus等等。
  • 相关阅读:
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    39. Combination Sum(dfs)
  • 原文地址:https://www.cnblogs.com/wzyexf/p/1451366.html
Copyright © 2011-2022 走看看