UpdatePanel触发javascript脚本技巧

       相信很多同志都已经遇到这个问题了.这个本身不奇怪.下面我们来具体讨论此问题.

一.预呈现数据无法更改

1.大家知道,预呈现的数据是无法更改的,以前可能提到过,这里再看demo,自定义一个控件

 [DefaultProperty( " Text " )]
    [ToolboxData(
" <{0}:JsControl runat=server></{0}:JsControl> " )]
    
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(
"<script src=\"xxxx.js\"></script>");
            output.Write(Text);
            output.Write(
"<script>alert('hello')</script>");
        }

四.几个误区

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就是这么实现的,有兴趣的可以下载一个用用

漏掉的请大家继续补充,这个问题比较的普遍,希望对大家有帮助。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值