ASP.NET AJAX入门系列(7):使用客户端脚本对UpdateProgress编程

在本篇文章中,我们将通过编写JavaScript来使用客户端行为扩展UpdateProgress控件,客户端代码将使用ASP.NET AJAX Library中的PageRequestManager,在UpdateProgress控件中,将添加一个Button,来允许用户取消异步更新,并且使用客户端脚本来显示或者隐藏进度信息。

 

主要内容

1.通过客户端脚本取消异步更新

2.通过客户端脚本显示或者隐藏进度信息

 

一.通过客户端脚本取消异步更新

1.创建一个Web页面并切换到设计视图。

2.在工具箱中双击ScriptManagerUpdatePanelUpdateProgress控件添加到页面中。添加后页面如下:

3.在UpdatePanel控件中添加一个Label控件并设置它的Text属性值为“Panel Rendered”。

4.添加一个Button控件并设置它的Text属性值为“refresh”。

5.在UpdateProgress控件中添加文本text Processing…,并添加一个HtmlButton控件并设置它的Text属性为cancle

6.双击refresh控件添加Click事件。

7.在ButtondClick事件处理中添加如下代码,人为的创建一个3秒钟的延迟并显示当前服务器的时间。

protected void Button1_Click(object sender, EventArgs e)
{
    System.Threading.Thread.Sleep(
3000);

    Label1.Text 
= DateTime.Now.ToString();
}

8.添加如下脚本,获取一个当前PageRequestManager类的实例,并创建一个函数调用abortPostBack方法来停止异步更新。

<script language="javascript" type="text/javascript">
<!-- 
var prm = Sys.WebForms.PageRequestManager.getInstance();

function CancelAsyncPostBack() {

    
if (prm.get_isInAsyncPostBack()) {

      prm.abortPostBack();

    }

}

// -->
</script>

9.设置HtmlButtonclick特性为CancelAsyncPostBack

10.添加如下的样式块到<head>元素之间。

<style type="text/css">

#UpdatePanel1 
{

  width
:200px; height:100px;

  border
: 1px solid gray;

}


#UpdateProgress1 
{

  width
:200px; background-color: #FFC080;

  bottom
: 0%; left: 0px; position: absolute;

}


</style>

11.保存并按Ctrl + F5运行。

12.单击refresh按钮,经过短暂的延时之后显示进度信息,完成异步更新之后UpdatePanel中的信息显示为当前的服务器时间。

13.单击refresh按钮并立即单击Cancle按钮结束异步更新,注意到UpdatePanel中的时间信息并没有更新。

二.通过客户端脚本显示或者隐藏进度信息

在下列情况下,UpdateProgress控件将不会自动显示:

    UpdateProgress控件关联的UpdatePanel之外的控件引发的异步更新。

    UpdateProgress控件没有关联任何UpdatePanel,不在UpdatePanel中的控件引发的异步更新(例如用代码实现的更新)。

下面的例子将展示一个不在UpdateProgress所关联的UpdatePanel中的控件所引发的异步更新时,如何显示UpdateProgress控件。

1.在我们前面所创建的页面中,切换到设计视图。

2.选中UpdateProgress控件,在属性窗口中,设置AssociatedUpdatePanelID属性为UpdatePanel1

3.在UpdatePanelUpdateProgress控件之外添加一个Button控件。

4.设置ButtonText属性值为Trigger,并设置ID属性为Panel1Trigger

5.选择UpdatePanel控件,在属性窗口中Triggers属性行单击ellipsis (…)

6.创建一个异步更新触发器,并设置控件IDPanel1Trigger

7.双击Trigger按钮添加Click事件。

8.在ButtondClick事件处理中添加如下代码,人为的创建一个3秒钟的延迟并显示当前服务器的时间,并附加上一条信息表示是由触发器引发的异步更新。

protected void Panel1Trigger_Click(object sender, EventArgs e)
{
    System.Threading.Thread.Sleep(
3000);

    Label1.Text 
= DateTime.Now.ToString() + " - trigger";
}

9.在代码窗口,在已有的<Script>脚本块中添加如下代码:



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

<!-- 

var prm = Sys.WebForms.PageRequestManager.getInstance();

function CancelAsyncPostBack() {

    
if (prm.get_isInAsyncPostBack()) {

      prm.abortPostBack();

    }


}


prm.add_initializeRequest(InitializeRequest);

prm.add_endRequest(EndRequest);

var postBackElement;

function InitializeRequest(sender, args) {

    
if (prm.get_isInAsyncPostBack()) {

        args.set_cancel(
true);
    }


    postBackElement 
= args.get_postBackElement();

    
if (postBackElement.id = 'Panel1Trigger') {

        $get('UpdateProgress1').style.display 
= 'block';                

    }


}


function EndRequest(sender, args) {

    
if (postBackElement.id = 'Panel1Trigger') {

        $get('UpdateProgress1').style.display 
= 'none';

    }


}


// -->

</script>

10.保存并按Ctrl + F5运行。

11.单击Trigger按钮,如下所示:


[翻译自官方文档]

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2006-11-12 22:59 TerryLee 阅读(11009) 评论(67)  编辑 收藏 所属分类: ASP.NETAJAX

  回复  引用    
#1楼 2006-11-13 08:49 | 小庄[匿名] [未注册用户]
呵呵,换古典样式了,以前那个样式看习惯了,差点认不出Terry同志了!
  回复  引用  查看    
#2楼 2006-11-13 10:32 | Hunts.C      
请问 'Sys'未定义 这个错误怎么解决?
  回复  引用  查看    
#3楼 [楼主]2006-11-13 11:34 | TerryLee      
@小庄[匿名]
呵呵,好几天没来写东西

换个样式,换个心情:)
  回复  引用  查看    
#4楼 [楼主]2006-11-13 13:00 | TerryLee      
@Hunts.C
完全卸载以前的各个版本,重新安装Beta2

问题是没有加载ASP.NET AJAX脚本文件
  回复  引用  查看    
#5楼 2006-11-13 16:03 | Hunts.C      
@TerryLee
我昨晚这么完全卸载过了~没能解决
今天早上在asp.net网站的论坛搜到关于这个问题的帖子,也一一试过了里面的办法,跟论坛里他们询问的结果一样,有些奇怪的方法,但对别人的不管用……
  回复  引用    
#6楼 2006-11-13 16:45 | charming[匿名] [未注册用户]
签到~~Lee加油!
  回复  引用    
#7楼 2006-11-13 16:48 | charming[匿名] [未注册用户]
@Hunts.C
你说的问题我是在重装beta2解决的:)
  回复  引用  查看    
#8楼 [楼主]2006-11-13 17:00 | TerryLee      
@Hunts.C
-_-

这样我也没有办法了,问问老赵?
  回复  引用    
#9楼 2006-11-14 21:56 | 哈哈[匿名] [未注册用户]
我也遇到这问题了 'Sys'未定义 我把
var prm = Sys.WebForms.PageRequestManager.getInstance();
移到函数里就没问题了。
  回复  引用  查看    
#10楼 [楼主]2006-11-15 12:51 | TerryLee      
@哈哈[匿名]
得找到一个最终的解决方案:-)
  回复  引用    
#11楼 2006-11-16 16:21 | ztk12 [未注册用户]
我也遇到过这个问题,是web.config的问题,用VS2005生成了一个,将原来的覆盖就好了!
  回复  引用  查看    
#12楼 2006-11-17 10:39 | 烈域      
在web.config文件system.web节里添加
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="Microsoft.Web.Script.Services.ScriptHandlerFactory, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add verb="GET" path="ScriptResource.axd" type="Microsoft.Web.Handlers.ScriptResourceHandler" validate="false"/>
</httpHandlers>
就可以了。
具体的可以查看AjaxControlToolkit项目内SampleWebSite的web.config配置
  回复  引用    
#13楼 2006-11-17 11:17 | 阿蒙[匿名] [未注册用户]
@Hunts.C
我想你的原因可能是这样:

你的ScriptManager控件放在body中
而你的javascript代码放在了ScriptManager控件之前的位置
因为html是逐行加载的
由于var prm = Sys.PageRequestManager.getInstance();在加载ScriptManager控件的js代码之前就被调用了,所以就出现了Sys未定义的情况
但是如果你把这行代码放在每个function中,或者把整段js代码放在ScriptManager控件之后,就不会出现这个问题了!
  回复  引用    
#14楼 2006-11-17 11:22 | 阿蒙[匿名] [未注册用户]
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}

请问T大,这段代码的意思就是:如果在异步处理中就终止当前的异步处理?
  回复  引用  查看    
#15楼 2006-11-17 11:57 | Kevin Wu      
我在普通页面使用 ajax ,怎么找不到ajax.dll引用的?
  回复  引用    
#16楼 2006-11-17 14:26 | guest [未注册用户]
没有范例下载呀
  回复  引用  查看    
#17楼 2006-11-17 17:25 | KiddLee      
在开始做“通过客户端脚本取消异步更新”的代码例子是出现了prm为空或不是对象的错误。感觉是下面代码的问题。
<script language="javascript" type="text/javascript">
<!--
var prm = Sys.WebForms.PageRequestManager.getInstance();

function CancelAsyncPostBack() {

if (prm.get_isInAsyncPostBack()) {

prm.abortPostBack();

}
}
// -->
</script>
后来修改为
<script language="javascript" type="text/javascript">
<!--
function CancelAsyncPostBack() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm.get_isInAsyncPostBack()) {

prm.abortPostBack();

}
}
// -->
</script>
或者向阿蒙说的将原来的代码放到ScriptManager之后就没问题了
  回复  引用  查看    
#18楼 [楼主]2006-11-18 17:54 | TerryLee      
@ztk12
直接建ASP.NET AJAX项目,Web.config已经配置好了
  回复  引用  查看    
#19楼 [楼主]2006-11-18 17:56 | TerryLee      
@阿蒙[匿名]
取消异步处理:
prm.abortPostBack();

上面那段是在初始化的时候设置可以取消
  回复  引用  查看    
#20楼 [楼主]2006-11-18 17:59 | TerryLee      
@Kevin Wu
Microsoft.Web.Extensions.dll
  回复  引用  查看    
#21楼 2006-11-18 23:03 | Kevin Wu      
thanks
  回复  引用  查看    
#22楼 2006-11-18 23:33 | Kevin Wu      
我自己写老是写不对哦,页面刷新还是整页的,郁闷,李大哥能否给个小点的例子或者告诉我哪里有我去看看?谢谢了
  回复  引用  查看    
#23楼 2006-11-19 08:33 | Kevin Wu      
谢谢李大哥,搞定了。。
以后有什么问题还是会请教你的哦。:)
  回复  引用  查看    
#24楼 [楼主]2006-11-19 21:43 | TerryLee      
@Kevin Wu
不用客气:)
  回复  引用    
#25楼 2006-11-23 15:46 | David Liao [未注册用户]
好东西,此网站我收藏了!
  回复  引用  查看    
#26楼 [楼主]2006-11-23 20:56 | TerryLee      
@David Liao
:)
  回复  引用    
#27楼 2006-12-20 20:36 | zzzXXX [未注册用户]
@哈哈[匿名]
没错啊,要移动到函数里面啊!晕四啊!

  回复  引用    
#28楼 2006-12-20 20:40 | zzzXXX [未注册用户]
@阿蒙[匿名]
终于明白了,太感谢了,高手啊!
  回复  引用  查看    
#29楼 2006-12-21 19:40 | Anthan      
我在GridView中的模板列中使用ImageButton调用后台的事件更新和删除数据,用了两个UpdateProgress,一个显示Updating一个显示Deleting。现在用脚本控制它们分别显示。但是老是不对,我猜想可能是在脚本中抓两个ImageButton的postBackElement.id 抓错了,不知道GridView中的怎么抓?
望指教一二...多谢
  回复  引用    
#30楼 2006-12-23 14:02 | susam119 [未注册用户]
很难记啊,又不会自动补充JS的东西。
  回复  引用  查看    
#31楼 [楼主]2006-12-23 16:14 | TerryLee      
@susam119
的确是,很容易写错JS代码
  回复  引用  查看    
#32楼 [楼主]2006-12-23 16:15 | TerryLee      
@Anthan
能不能把代码贴出来一部分看一下?
  回复  引用  查看    
#33楼 2006-12-24 15:52 | 丹心猪(Dansinge)      
学习到些
  回复  引用    
#34楼 2007-01-19 11:03 | Henry [未注册用户]
@阿蒙[匿名]
你的方法确实正确,不过现在点了按钮后报了个postBackElement未定义,不知道为什么
  回复  引用    
#35楼 2007-01-19 11:06 | Henry [未注册用户]
晕,要把var postBackElement;也拿到外面才行,要不然在别的函数里怎么可能找到呢
  回复  引用    
#36楼 2007-02-21 19:19 | panda [未注册用户]
我用的是正式版,在例二中,不用脚本也会显示updateProcessing...
  回复  引用  查看    
#37楼 2007-02-24 09:16 | 若寒      
@KiddLee
谢谢!终于OK了.
我觉得没有必要把prm定义为全局的.
  回复  引用    
#38楼 2007-02-26 20:04 | protorock [未注册用户]
请教搂主一个问题:如果将你例子1中的javascript脚本块放置在<head>中,脚本执行就会出错;而放置在<asp:ScriptManager>后就能正确执行。这是为什么将呢?
  回复  引用    
#39楼 2007-02-26 20:08 | protorock [未注册用户]
是不是因为浏览器加载处理过程的缘故?

谢谢!
  回复  引用    
#40楼 2007-03-07 15:20 | andy [未注册用户]
我的也是“Sys”未被定義
---------------------------
錯誤
---------------------------
發生執行錯誤。
要偵錯嗎?

行: 32
錯誤: 'Sys' 未被定義
---------------------------
是(Y) 否(N)
---------------------------
  回复  引用    
#41楼 2007-03-09 17:46 | renny [未注册用户]
请问: 如何在页面加载完之前也能够显示UpdateProgress,而不仅仅是触发服务器事件,,多谢!

msn:renny@sina.com
  回复  引用    
#42楼 2007-03-11 10:21 | huldh [未注册用户]
正式版的后面加的那些js全部可以不要的!
  回复  引用    
#43楼 2007-03-19 13:15 | ouguba [未注册用户]
@andy
js代码:var prm = Sys.WebForms.PageRequestManager.getInstance();放在ScriptManager控件之后,就不会有这样的问题了。
  回复  引用    
#44楼 2007-03-20 15:55 | harry [未注册用户]
@TerryLee
@Kevin Wu
Microsoft.Web.Extensions.dll
---------------------
我没有找不到这个dll。只找到是System.Web.Extension.dll
不知是否这个
  回复  引用    
#45楼 2007-03-28 17:18 | JAMES [未注册用户]
cencel的按钮不能用啊!
  回复  引用    
#46楼 2007-04-14 14:40 | renzhonghao [未注册用户]
看了各位老大的帖子,我调试起来竟然一个错都没报,真是顺利啊!!
  回复  引用  查看    
#47楼 2007-05-11 11:49 | Nick Yao      
以下这句
$get('UpdateProgress1').style.display = 'block';
是不是要修改成
$get('<%= UpdateProgress1.ClientID %>').style.display = 'block';
才奏效啊?
  回复  引用    
#48楼 2007-09-16 01:56 | hujunhua QQ10646337 [未注册用户]
怎么通过一段客户端的JS脚本 直接操作更新某个空间UpdatePanel?
  回复  引用    
#49楼 2007-10-20 11:04 | testtest [未注册用户]
可是Cancel按钮根本不起作用阿,根本没有取消异步更新,这是怎么回事啊
  回复  引用 &