由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. firefox的console log功能

    http://www.ruanyifeng.com/blog/2011/03/firebug_console_tutorial.html Firebug是网页开发的利器,能够极大地提升工作效率. 但是 ...

  2. idea 从github下载项目提示 file name too long 的解决方案

    1.找到git shell命令行 2运行如下命令 git config --global core.longpaths true 附地址https://github.com/Strider-CD/st ...

  3. 用nexus搭建maven私服

    首先介绍一下背景,公司访问外网有限制,项目组大部分人员不能访问maven的central repository,因此在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到这台私服上 环 ...

  4. 如何用Matlab将cell数据写入文件

    我们知道,一般的文件读写函数是不接受直接将cell内容(非数值)直接写入文件的, 例如:dlmwrite('o.txt', C, 'delimiter', '\t');%C 为cell类型数据,会报错 ...

  5. UI Automation Test

    UI Automation test is based on the windows API. U can find the UI Automation MSDN file from http://m ...

  6. Spring中使用Schedule调度

    在spring中两种办法使用调度,以下使用是在spring4.0中. 一.基于application配置文件,配置入下: <bean id="jobDetail" class ...

  7. ibatis 使用 in 查询的几种XML写法

    原文地址:http://blog.csdn.net/dracotianlong/article/details/35303593 这里摘抄学习 1.传入参数是数组 <select id=&quo ...

  8. IOS Alcatraz Xcode6.4安装指南

    1.Alcatraz Alcatraz是Xcode上的插件管理器,用过notepad++应该印象深刻,近来在一部新机器 按以前的安装方法安装老是安装不成功.特意查找了下资料,最后安装成功. 2.安装过 ...

  9. MVC中使用Ueditor

    配置.net mvc4项目使用ueditor编辑器. 1.首先下载Ueditor1.3.6开发版(http://ueditor.baidu.com/website/download.html) 2.将 ...

  10. adapter.notifyDataSetChanged(); 没有反应

    为什么是这样,以下是我总结的一些原因: 1.数据源没有更新,调用notifyDataSetChanged无效. 2.数据源更新了,但是它指向新的引用,调用notifyDataSetChanged无效. ...