脚本注册


ASP.NET 2.0脚本支持

–不推荐,或者说不要使用Response.Write方法

不止是破坏了整个页面模型,特别是开发控件

–使用Framework所支持的方法

RegisterArrayDeclaration

RegisterClientScriptBlock

RegisterClientScriptInclude

RegisterClientScriptResource

RegisterExpandoAttribute

RegisterHiddenField

RegisterOnSubmitStatement

RegisterStartupScript


        ClientScriptManager cs = this.ClientScript;

        //创建JavaScript数组

        //<script type="text/javascript">

        //<!--

        //var Hello =  new Array(1, 2, 3);

        -->

        //</script>

        //但当Array(5)的时候是表示长度为5的数组

        cs.RegisterArrayDeclaration("Hello", "1", "2", "3");


        //为对象输出一个函数,为true时自动加上<script></script>

        // <script type="text/javascript">

        //<!--

        //function helloWorld(){alert(1);}// -->

        //</script>

        cs.RegisterClientScriptBlock(this, GetType(), "HelloWorld", "function helloWorld(){alert(1);}",true);


        //添加对JS脚本的引用

        //<script src="HelloWorld.js" type="text/javascript"></script>

        cs.RegisterClientScriptInclude("HelloWorld","HelloWorld.js");


        //为指定控件添加额外的属性,一定要为ClientID,因为生成的在客户端表示不一样

        //<script type="text/javascript">

        //<!--

        //var Button1 = document.all ? document.all["Button1"] : document.getElementById("Button1");

        //Button1.Hello = "World";

        -->

        //</script>

        cs.RegisterExpandoAttribute(this.Button1.ClientID,"Hellod","World");


        //添加个隐藏值

        //<input type="hidden" name="hello" id="hello" value="world" />

        cs.RegisterHiddenField("Hello","World");


        //confirm

        //<script type="text/javascript">

        //<!--

        //function WebForm_OnSubmit() {

        //return window.confirm('Do you really want to submit the form?');

        //return true;

        //}

        -->

        //</script>

        cs.RegisterOnSubmitStatement(this.GetType(), "HelloWorld", "return window.confirm('Do you really want to submit the form?')");


        //添加一个Script,最开始运行

        //<script>alert('The page has loaded!')</script>

        cs.RegisterStartupScript(this.GetType(), "HelloWorld", "<script>alert('The page has loaded!')</script>");


•在异步更新的环境中注册脚本,所以当使用Response.Write();就会报错了

–使用ScriptManager对应的静态方法

–新方法与原有方法的区别:

•方法都会都接受一个参数

•并非所有注册过的脚本都会生效

•RegisterExpandoAttribute方法多了个encode参数

–新方法可以用来完全替换原有方法

•在非异步回送环境中会使用ClientScriptManager的对应方法进行注册


              <asp:ScriptManager ID="ScriptManager1" runat="server">

              </asp:ScriptManager>


              <asp:UpdatePanel ID="UpdatePanel1" runat="server">

                     <ContentTemplate>

                            <%= DateTime.Now %>

                            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click1" />

                     </ContentTemplate>

              </asp:UpdatePanel>


              <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode=Conditional>

                     <ContentTemplate>

                            <%= DateTime.Now %>

                     </ContentTemplate>

              </asp:UpdatePanel>


       protected void Button1_Click1(object sender, EventArgs e)

       {

              ScriptManager.RegisterStartupScript(this.UpdatePanel1, this.GetType(), "UpdatePanel1", "alert(1)", true);

              ScriptManager.RegisterStartupScript(this.UpdatePanel2, this.GetType(), "UpdatePanel2", "alert(2)", true);

       }


结果,当点击Button的时候,只刷新了UpdatePanel1.只有当UpdatePanel2的UpdateMode为Always或不写时才会更新

另,ScriptManager.RegisterStartupScript();也可以直接对整个PAGE操作了

l          ​错误处理

服务器端ScriptManager设置

–AllowCustomErrorsRedirect属性:遇到错误是否自动根据web.config中的设置跳转,默认值为True。

–AsyncPostBackError事件:异步刷新中出现错误时触发的事件。

–AsyncPostBackErrorMessage属性:客户端接受到的错误信息。


Web.Config中<customErrors mode="On" defaultRedirect="~/Error.aspx"></customErrors>

Error.aspx为自定义错误

页面中

              <asp:ScriptManager ID="ScriptManager1" runat="server" AllowCustomErrorsRedirect="true">

             </asp:ScriptManager>



<asp:ScriptManager ID="ScriptManager1" runat="server" AllowCustomErrorsRedirect="false"

 当服务端抛出个异常的时候,会跳出一段XXXXXX的错误          

添加如下事件

<asp:ScriptManager ID="ScriptManager1" runat="server" AllowCustomErrorsRedirect="false"

OnAsyncPostBackError="ScriptManager1_AsyncPostBackError">  </asp:ScriptManager>

       protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)

       {

              ScriptManager.GetCurrent(this).AsyncPostBackErrorMessage = e.Exception.Message;

      }

但这样的话会弹出一个对话框

比如在页面中添加如下

              <div id="error"></div>

              <script type="text/javascript" language="javascript">

                     Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, e)

                     {

                            e.set_errorHandled(true);

                            $get("error").innerHTML = "Sorry, an error has occurred: " + e.get_error().message;

                            setTimeout(function(){ $get("error").innerHTML = ""; }, 3000);

                     });

             </script>


客户端编程

–响应PageRequestManager的endRequest事件。

–将errorHandled属性设为true。


l          ​动态操作​  ​

要点:

–在生命周期的Load阶段结束之前动态添加控件

–为每个动态控件指定明确的ID

–不要为页面中的UpdatePanel添加新的Trigger

原因

–使用ContentTemplateContainer属性向UpdatePanel内添加新控件


    protected void Page_Load(object sender, EventArgs e)

    {

              UpdatePanel up = new UpdatePanel();

              up.ID = "UpdatePanel1";

              this.Form.Controls.Add(up);


              LiteralControl lc = new LiteralControl(DateTime.Now.ToString());

              up.ContentTemplateContainer.Controls.Add(lc);


              Button btn = new Button();

              btn.Text = "Refresh";

              up.ContentTemplateContainer.Controls.Add(btn);

    }


演示:​​http://www.jeffzon.net/Samples/SwitchPartManager/Default.aspx​​​

l          ​实现原理简要分析

传统的PostBack

       Init               

       Load State     

       Process PostBack

       PostBack Events

       Save State

       ProRender

       Render

       Upload

异步PostBack

- PageRequestManager -- ProRender

       ProRender

       Upload


请求内容数据大小没有任何减少

–采集Form中所有<input />并发送

–包含ViewState

尽可能减少客户端接受到的数据大小

–使用多个UpdatePanel包含多个部分

–UpdateMode尽量不要设为Always


什么样的UpdatePanel会更新?

–UpdateMode为Always

–AsyncPostBackTrigger的条件被满足

–Update方法被调用

–客户端告诉服务器端需要更新

ChildrenAsTriggers属性的效果体现在客户端

通过元素的ID、UniqueID与DOM结构共同判断




l          ​相关资源


官方站点:

–         ​​http://ajax.asp.net​

ScottGuthrie的blog:

–         ​​http://weblogs.asp.net/scottgu/​

WebCast AJAX作者视频blog:( 本系列视频都是参考此BLOG)

•​MSDN​中文网站​​http://www.microsoft.com/china/msdn​

•​MSDN​中文网络广播​​http://www.msdnwebcast.com.cn​

•​MSDN Flash ​http://www.microsoft.com/china/newsletter/case/msdn.aspx​

•​MSDN​开发中心 ​​http://www.microsoft.com/china/msdn/DeveloperCenter/default.mspx​