由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇(二)通过自己模拟HTML标签事件与服务器交互,讲了ASP.NET的服务器控件是怎么render成HTML后市怎么“调用”后台方法的,有同学看了后问了我个问题:你讲的方式确实可以,但我遇到的问题时这样的,我想让自己写的DIV点击一下提交表单,我是自己写post好呢还是用页面上的__doPostBack方法好呢?

我想了一下,觉得都不好。若是用自己写隐藏域,然后赋值提交的方法,原理虽然正确,但我们需要做很多额外工作;如果调用页面上自动生成的__doPostBack,万一页面上没有服务器控件,那么页面页面上也就不会有这个方法了,而且并不是所有的服务器控件都生成这个方法,退一万步,要是微软改接口,方法名字变了怎么办?

废话了半天,我们因该怎么处理这种情况呢?正如预期,微软又替我们想好了,IPostBackEventHandler接口就是做这事儿的,看个例子

<form id="form1" runat="server">
<div id="divTest" onclick="clientPostback(this);">Click to Post Back</div> <script type="text/javascript">
function clientPostback(obj) {
setTimeout(postBackClientHandler.replace(/arg_placeholder/g,obj.id), 0);
}
</script>
</form>

页面上有个DIV,点击的时候调用JavaScript clientPostBack方法,我们知道所谓JavaScript调用后台都是通过表单提交的方式实现的,在clientPostBack中有条奇怪的语句, setTimeout(postBackClientHandler.replace(/arg_placeholder/g,obj.id), 0); ,看看后台代码,就明白这是什么了

public partial class Default : System.Web.UI.Page,IPostBackEventHandler
{ protected override void OnPreRender(EventArgs e)
{
PostBackOptions pbo = new PostBackOptions(this, "arg_placeholder", "", false, false, false, true, false, "");
string clientScript = Page.ClientScript.GetPostBackEventReference(pbo);
string postBackClientHandler = string.Format("\nvar postBackClientHandler=\"{0}\";\n", clientScript);
Page.ClientScript.RegisterStartupScript(typeof(Default), "postBackClientHandler", postBackClientHandler, true);
base.OnPreRender(e);
} public void RaisePostBackEvent(string eventArgument)
{
Response.Write("Event argument is " + eventArgument);
}
}

首先让类实现IPostBackEventHandler接口,实现RaisePostBackEvent方法,MSDN上市这么解释这个方法的:当由类实现时,使服务器控件能够处理将窗体发送到服务器时引发的事件。这个方法就是JavaScript 提交表单后.NET自动执行的方法,我们把页面传来的参数输出。

在页面的PreRender事件处理程序中,使用PostBackOptions对象创建并注册客户端提交表单所用的脚本,想看明白这段代码,首先得了解PostBackOptions对象。MSDN上这么解释PostBackOptions:指定如何生成客户端 JavaScript 以启动回发事件。看看这个对象构造函数的几个参数

参数
targetControl
    类型:System.Web.UI.Control
         用于接收回发事件的 Control
argument
    类型:System.String

        在回发事件期间传递的可选参数。
actionUrl
    类型:System.String

        回发的目标。
autoPostBack
    类型:System.Boolean

        如果需要响应用户操作而自动将窗体回发到服务器,则为 true;否则为 false。
requiresJavaScriptProtocol
    类型:System.Boolean

        如果 javascript: 前缀是必需的,则为 true;否则为 false。
trackFocus
    类型:System.Boolean

        如果回发事件应将页返回到当前的滚动位置并将焦点返回到目标控件,则为 true;否则为 false。
clientSubmit
    类型:System.Boolean

         如果回发事件可以由客户端脚本引发,则为 true;否则为 false。
performValidation
    类型:System.Boolean

         如果在回发事件发生之前要求在客户端进行验证,则为 true;否则为 false。
validationGroup
    类型:System.String

         一个控件组,当该控件组回发到服务器时,PostBackOptions将引发对它的验证。

代码中 string clientScript = Page.ClientScript.GetPostBackEventReference(pbo); 是整个注册的核心,通过这条语句就可以获取注册到客户端的脚本语句,然后注册到页面。看看页面生成的代码

<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>
<script type="text/javascript">
//<![CDATA[ var postBackClientHandler="__doPostBack('__Page','arg_placeholder')";
//]]>
</script>

通过代码分歧可以看出string clientScript = Page.ClientScript.GetPostBackEventReference(pbo); 语句得到的结果是 __doPostBack('__Page','arg_placeholder')。我们通过string postBackClientHandler = string.Format("\nvar postBackClientHandler=\"{0}\";\n", clientScript); 语句将其包装成一个字符串变量注册到页面,否则它是一个函数调用语句,页面会不停的被提交(有兴趣同学可以试试将其直接注册到页面)。

这样回头看看客户端DIV onclick方法是什么意思

postBackClientHandler是字符串”__doPostBack('__Page','arg_placeholder')”

postBackClientHandler.replace(/arg_placeholder/g,obj.id) 这条语句是把字符串中的”arg_placeholder”替换为我们希望传递给服务器的参数,也就是通过参数隐藏域提交到服务器的数据,这样我们写的客户端方法实际上是这样

function clientPostback(obj) {
setTimeout("__doPostBack('__Page','divTest')", 0);
}

至于setTimeout是因为我们得到是一个字符串而不是JavaScript语句,使用setTimeout和eval效果类似,将字符串转为可执行语句,这时是不是既方便又可靠了呢。

使用IPostBackEventHandler让JavaScript“调用”回传事件的更多相关文章

  1. javascript中onclick事件能调用多个方法吗

    Q: javascript中onclick事件能调用多个方法吗? A: 可以的,方法如下onclick="aa();bb();cc();"每个方法用“;”分号隔开就行了

  2. JavaScript的 onclick 事件是如何调用jquery 方法的

    看见个不错的问答,关于JavaScript的 onclick 事件是如何调用jquery 方法的,特此标注,链接如下:http://segmentfault.com/q/101000000033350 ...

  3. JavaScript中的事件对象

    JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...

  4. Android中Webview使用javascript调用事先定义好的Java函数

    1. 首先定义好一个类,专们用于给javascript调用 public class JavaScriptInterface { // share your news public void shar ...

  5. JavaScript HTML DOM 事件

    JavaScript HTML DOM 事件 HTML DOM 使 JavaScript 有能力对 HTML 事件做出反应. 实例 Mouse Over Me 对事件做出反应 我们可以在事件发生时执行 ...

  6. html,JavaScript调用winfrom方法

    ---恢复内容开始--- 目的: 在动画上面添加点击事件,通过JavaScript调用winfrom方法 1.创建一个页面 using System; using System.Collections ...

  7. 深入理解javascript中的事件循环event-loop

    前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...

  8. JavaScript Dom 绑定事件

    JavaScript  Dom 绑定事件 // 先获取Dom对象,然后进行绑定 document.getElementById('xx').onclick document.getElementByI ...

  9. javascript调用Flash里对象的方法(函数)搞了五个小时。

    搞了几个小时后,才发现,之前走的路是错的. 今天在Firefox浏览器上测试一个javascript调用Flash中的一个对象的方法时遇到问题了, 一搞就整整搞了一个下午. 我记得之前我用Flash8 ...

随机推荐

  1. java-base64编码和解码

    一.反射/*** * encode by Base64 */ public static String encodeBase64(byte[]input) throws Exception{ Clas ...

  2. 编译运行java程序出现Exception in thread "main" java.lang.UnsupportedClassVersionError: M : Unsupported major.minor version 51.0

    用javac编译了一个M.java文件, 然后用java M执行,可是出现了下面这个错误. Exception in thread "main" java.lang.Unsuppo ...

  3. configure: error: *** libpopt not found 解决方法

    ubuntu (deb) $ apt-cache search popt|headlibpopt-dev - lib for parsing cmdline parameters - developm ...

  4. noip2012-day2-t2

    [问题描述] 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们 ...

  5. 今个忽然晓得,原来radio不是普通去获取值的!

    今日,写js校验.对于不太会的,总是陌生的.碰见radio的取值,习惯的用document.getElementsByName("")[0].value去获取值,却忘记了radio ...

  6. Java LinkedList 源码剖析

    LinkedList同时实现了List接口和Deque接口,也就是说它既可以看作一个顺序容器,又可以看作一个队列(Queue),同时又可以看作一个栈(Stack).这样看来,LinkedList简直就 ...

  7. Win7 64位qt-windows-x86-msvc2015-5.6.0 DLL依赖库打包

    今天开始系统的学习QT,第一个测试的问题就是在纯净的系统中如何正常运行,也就是找出QT生成的exe的依赖库问题 网上搜了下可以简单粗暴的用 D:\Qt\Qt5.6.0\5.6\msvc2015\bin ...

  8. 实验一报告--认识DOS

    实验一  DOS命令解释程序的编写 13物联网             黄鸿佳              201306104107 一. 实验目的 (1)认识DOS: (2)掌握命令解释程序的原理: ...

  9. iOS进阶_三方使用步骤

    一.配置环境(:后为在终端输入的命令) 打开终端 查看自己电脑的Ruby环境:gem sources -l 如果环境已经是淘宝镜像了,此时不需要再进行环境的修改. 如果不是,发送gem sources ...

  10. javascript练习-方法借用

    方法借用其实也可以叫做多重继承 var generic = { //返回一个字符串,这个字符串包含构造函数的名字(如果构造函数包含名字) //这个以及所有非继承来的,非函数属性的名字和值 toStri ...