updatepanel触发javascript脚本技巧
2007-10-10 20:30
by
clingingboy,
5959
visits,
收藏,
编辑
相信很多同志都已经遇到这个问题了.这个本身不奇怪.下面我们来具体讨论此问题.
一.预呈现数据无法更改
1.大家知道,预呈现的数据是无法更改的,以前可能提到过,这里再看demo,自定义一个控件
[defaultproperty("text")]
[toolboxdata("")]
public class jscontrol : webcontrol
{
[bindable(true)]
[category("appearance")]
[defaultvalue("")]
[localizable(true)]
public string text
{
get
{
string s = (string)viewstate["text"];
return ((s == null) ? string.empty : s);
}
set
{
viewstate["text"] = value;
}
}
protected override void onprerender(eventargs e)
{
text = "hello,you can't change me";
base.onprerender(e);
}
protected override void rendercontents(htmltextwriter output)
{
output.write(text);
}
}
aspx页面
protected void button1_click(object sender, eventargs e)
{
jscontrol1.text = "i want to change the text property";
}
你会发现你并未更改属性.这牵涉到控件生命周期的执行.为什么要说这个,因为控件的大部分脚本都是在预呈现中注册的.
这有什么问题吗? 其本身想法很好,脚本在此事件(指onprerender)中注册,注册脚本资源在前(控件夹中间),脚本初始化在最后.这符合javascript的使用原则,先导入脚本,然后有标签,初始化的脚本须放在标签后面.
二.updatepanel引起的问题
上面的问题如果是服务器提交回传的则可行,主要问题是我们要用ajax无刷新注册脚本.以下我们再来看asp.net2.0内置的treeview控件,拖个控件要页面看其生成的html代码,如下图
图一
你已经看到很多的脚本注册和初始化了.
我们来测试下updatepanel能干什么事情,我们设置其属性visible为false到true
借助firebug的威力我们来看下updatepanel在无刷新状态下返回给了我们什么
图二
下面再点下节点,如下图
图三
出错了,大家可能也遇到过此情况,很正常嘛,updatepanel没有为我们注册脚本也没未我们初始化,在属于正常现象,updatepanel只管其容器里面的,其他的不归它管.
三.解决方法
要解决treeview控件,我是想不出来,这个控件算是在asp.net ajax模式下算是完蛋了.为了迎合asp.net ajax框架的运用,我们需要知道updatepanel无刷新更新范围,当我们自己定义控件的时候就需要注意.
1.控件本身标签
2.控件内部
3.updatepanel容器内部
若想使用updatepanel更新数据后再触发客户端事件的,有以下方案
1.通过更改现有控件属性,如
button1.attributes["onmouseover"] = "alert('hello')";
2.在呈现过程中脚本初始化
第一种方法简单运用还可以,复杂就不行了,我们还是需要把脚本封装好跟控件结合使用的,我们不再在预呈现中注册脚本,而在呈现中实现(即redercontent方法).
我们只要保证脚本资源在前,初始化在后,控件在中间这一原则就可以了...以下方法是可行的
如下
protected override void rendercontents(htmltextwriter output)
{
output.write("");
output.write(text);
output.write("");
}
四.几个误区
1.验证控件在ajax框架中可以完好使用
其实是其加载了一段脚本,不然其也会挂掉
2.状态保留
在updatepanel中更新数据后,再postback,无刷新更新的数据状态还保留
3.更新数据后执行客户端脚本
曾经我们天真的会这么写
protected void button1_click(object sender, eventargs e)
{
label1.text = "alert('hello')";
}
结果什么也没发生,window.onload事件已过,除非你刷新(可你不想刷新),不然没人帮你触发。
谁来触发?微软帮我们准备好了。你要的大概就是这个了,数据更新前后都是一个事件触发。我们可以围绕着这两个事件为控件做点事情。这个状态适合于数据取到后就立马触发的需要。
sys.webforms.pagerequestmanager.getinstance().add_beginrequest(beginrequesthandler);
sys.webforms.pagerequestmanager.getinstance().add_endrequest(endrequesthandler);
function beginrequesthandler(sender, args)
{
var elem = args.get_postbackelement();
activatealertdiv('visible', 'alertdiv', elem.value + ' processing');
}
function endrequesthandler(sender, args)
{
activatealertdiv('hidden', 'alertdiv', '');
}
function activatealertdiv(visstring, elem, msg)
{
var adiv = $get(elem);
adiv.style.visibility = visstring;
adiv.innerhtml = msg;
}
其他的话我们也可以更改控件属性,就如加个onclick事件什么的都可以
五.另类解决方法
此方法比较的绝,但用起来比较的爽。updatepanel之所以无法获取到脚本数据,是因为其获取范围还不够。。。接着的想法是:
照样无刷新取数据,但取回来的数据跟postback回来的数据一样。
可能有人说会比较耗性能,那都是相对的。不过也是一个很好的想法。telerik公司的radajaxpanel就是这么实现的,有兴趣的可以下载一个用用
漏掉的请大家继续补充,这个问题比较的普遍,希望对大家有帮助。
绿色通道:好文要顶关注我收藏该文与我联系
categories:
add your comment
15 条回复
957120
#1楼 bbqqw[未注册用户]2007-10-10 21:17
谢谢分享,学习中
回复 引用
#2楼 天涯追梦人[未注册用户]2007-10-10 21:52
谢谢你哦。写了那么多好东西,我是被博客园里http://webabcd.cnblogs.com.cn这位大哥来介绍来的。在学习控件开发,看了你的那系列的文章写的真是太帮了,在这里谢谢你了哦。如果不怕麻烦的话以后多向你请教哦。我的吃才从学校出来的学生,出来工作已经五个月了,感觉好多东西不会,想把基础东西打牢固再学习新东西。请多指教。我的qq289386000 msn 是tianx08@163.com
回复 引用
#3楼[楼主] clingingboy 2007-10-10 22:08
@天涯追梦人
比我长,我才刚工作4个月,跟你一样
回复 引用 查看
#4楼 cat chen 2007-10-11 00:58
不太明白。第一个例子和javascript有什么关系?另外asp.net ajax中所有脚本都应该用scriptmanager来注册吧,直接在htmltextwriter输出脚本不是一个好办法,因为你这样输出的脚本在html中间,而不是顶端。
回复 引用 查看
#5楼[楼主] clingingboy 2007-10-11 01:23
@cat chen
刚开始说预呈现,主要是为了说传统脚本注册的做法.
我试了一下scriptmanager的注册方法,果然可以.
我误以为scriptmanager的注册方法和clientscriptmanager的注册方法是一样的,只做了个适配,刚才又reflector了下,里面还有个scriptregistrationmanager类.
这个比较的不错,谢谢.当然能用注册就最好了.直接输出也是不得已而为之
回复 引用 查看
#6楼 peterchen[未注册用户]2007-10-11 04:39
学习中。
回复 引用
#7楼 cat chen 2007-10-11 07:17
@clingingboy
嗯……其实就是用scriptmanager就可以了,新增加的那个参数能够让scriptmanager知道这段脚本是否在一个正在更新的updatepanel内,从而决定是否执行它。
回复 引用 查看
#8楼 天涯追梦人[未注册用户]2007-10-11 21:58
@clingingboy
但是我感觉你的技术好强哦。佩服,我是五月份出来的,和你比感觉有大的差距。向你学习
回复 引用
#9楼[楼主] clingingboy 2007-10-11 22:40
@天涯追梦人
幻觉幻觉,学下去就知道了,其实没那么难的.学好自己需要就行了
回复 引用 查看
#10楼 梦☆幻☆空 2007-10-12 10:49
今天也注册了个博客园帐号,以后多指点哦。我对控件这块确实是不怎么熟悉。才开始学。最近在考虑买那你介绍的那本书,谭振林老师写的那本。努力向你们学习。惭愧。以前上学的时候没有电脑,没怎么好好学。工作了才感觉技术上好差劲。努力学习中!
回复 引用 查看
#11楼 丹心猪(dansinge) 2007-10-12 13:16
mark
回复 引用 查看
#12楼 kid wang[未注册用户]2007-11-02 10:30
mark
回复 引用
#13楼 丁一 2007-11-08 08:44
--引用--------------------------------------------------
cat chen: @clingingboy
嗯……其实就是用scriptmanager就可以了,新增加的那个参数能够让scriptmanager知道这段脚本是否在一个正在更新的updatepanel内,从而决定是否执行它。
--------------------------------------------------------
@cat chen
好像 scriptmanager 是ajax特有的吧.
如果对于控件开发, 没办法知道使用者是否安装了ajax,那又如何使用 scriptmanager ?
回复 引用 查看
#14楼 enzo 2007-11-12 18:46
@丁一
控件开发是另一回事 但开发出来之后 使用者自然知道是否有没有用ajax
其次就算是控件使用 即使在updatepanle内调用js也不用这么麻烦
回复 引用 查看
注册用户登录后才能发表评论,请 登录 或 注册,返回博客园首页。
最新it新闻:
» 更多新闻...
最新知识库文章:
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/