当前位置: 首页 > news >正文

AJAX如何用于Web部件

原文地址:http://sharethispoint.com/archive/2006/11/15/Build-web-parts-with-ajax.aspx
如何在开发Web部件时使用ajax呢?我们将以一个样子类似MOSS 2007中KPI和BDC Web部件的WebPart为例来说明。如果你对ajax一点都不了解,推荐学习TerryLee的ajax入门系列。
ASP.net2.0有一个很酷的新特性叫作客户端脚本回调。脚本回调主要使我们可以使用javascript调用服务器端程序中的方法,然后根据结果来做一些操作。这就使我们可以动态更新页面的某一部分内容,正如将在我们下面的WebPart中看到的,而不必刷新整页。关于在.net2.0中使用客户端脚本回调,可以参考下面的文章地址(http://msdn.microsoft.com/msdnmag/issues/04/08/CuttingEdge/),其中做出了详细的解释。但是如何确切的将其使用与我们的代码中,文章并没有详细介绍。事实上脚本回调特性是集成到.net中的,我们可以方便的拿来使用。
本示例中我们假设有这么一个WebPart,它需要很长的时间才能显示出内容。为了解决这个问题,给用户更好的体验,我们决定让render方法在WebPart刚刚载入时只输出一个空的div标签,然后我们通过ajax来替换div的内容,使其显示出实际需要的内容。这样,用户就可以在页面载入后在我们的WebPart完成内容载入前先看一看其他的内容。

下面我们就开始。

首先我们先创建一个新的WebPart项目。在我们的WebPart类中添加下面的命名空间。

using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;


想要使.net知道我们的类要使用脚本回调,必须实现System.Web.UI.IcallbackEventHandler接口。

public class TreeViewRollUp:WebPart,ICallbackEventHandler


IcallBackEventHandler接口有两个方法,public string GetCallbackResult()和 public void RaiseCallbackEvent(string eventArgs),稍后将对其进行介绍。
我们先定义两个变量

private string datadiv; // 用于保存div标签名称
private string ajaxdata; // 用于保存ajax返回的数据


datadiv变量保存了html中的我们打算输出内容的div标签的id。这个div标签的名称在一个WebPart实例中必须唯一。如果始终是一个固定名称,那么当我们在一个页面中有两个webpart的实例时它们有可能会替换对方的内容。
在webpart的RenderContents方法中加入下面的代码:

protected override void RenderContents(HtmlTextWriterwriter)
{
this .datadiv = this .ClientID + " content " ; // 使用WebPart实例的客户端id加上一个给定的名称
writer.Write( " <divid=\ "" +this.datadiv+ " \ " ><imgsrc=\ " / _layouts / images / GEARS_AN.GIF\ " width\ " 150 \ " ></div> " );
}


我们在最后一行的div标签中加了一个进度条的小gif图。这里直接用了WSSv3中的图片。

在OnLoad中粘贴如下代码:

protected override void OnLoad(EventArgse)
{
this .datadiv = this .ClientID + " content " ;
string js = Page.ClientScript.GetCallbackEventReference( this , " 'blah' " , " filldiv " , " ' " + this .datadiv + " ' " , true );
string contentloader = " varajaxcommands='';window.οnlοad=ajaxloader;functionajaxloader(){eval(ajaxcommands);}functionfilldiv(arg,ctx){varmydiv=document.getElementById(ctx);mydiv.innerHTML=arg;} " ;

if (Page.ClientScript.IsClientScriptBlockRegistered( " contentloader " ) == false )
Page.ClientScript.RegisterClientScriptBlock(Page.ClientScript.GetType(),
" contentloader " ,contentloader, true );

Page.ClientScript.RegisterStartupScript(
this .GetType(), " myloader " + this .ClientID, " ajaxcommands=ajaxcommands+\ "" +js+ " ;\ " ; " , true );//使用WebPart实例的客户端id加上一个给定的名称作为脚本的Key
base .OnLoad(e);
}


在该方法中注册有两块不同的javascript块 。
第一个字符串js的值来源于GetCallbackEventReference。GetCallbackEventReference方法用于返回执行回调服务器获取数据的javascript。我们传递了:一个当前控件(webpart)的引用;“Blah”,作为初始数据当回调启动后将被传递到我们的服务器端组件;当回调结束后调用的Javascript方法的名字;我们的标记内容的div标签的名字;异步开关设为true这些必要的参数。
通过该方法生成的javascript类似于下面的样子:

WebForm_DoCallback('ctl00$m$g_a010b3bd_1a68_40f9_b46b_f87050cf516f','blah',filldiv,'ctl00_m_g_a010b3bd_1a68_40f9_b46b_f87050cf516fcontents', null , true );


我们可以将这段javascript用于一个button的OnClick事件来启动回调并填充div标签。
在本例中,我们不希望用户还要点击什么的才能继续WebPart的载入。所以我们要在浏览器载入页面时调用WebForm_DoCallback 方法。这是用contentloader字符串来实现的。Contentloader字符串定义了一个javascript变量, ajaxcommands, 用来保存我们准备执行的一些命令。同时,我们设置window.onload事件使其执行ajaxloader方法。当ajaxloader方法运行时将通过eval函数执行所有存在ajaxcommands变量中的命令。
为什么这么写呢?这是因为如果我们在一个页面里有多于两个的ajax webpart的实例时,每个实例都将会通过window.onload事件来载入数据,这样问题就产生了。只有最后设定的事件处理(Event Handler)会被执行,并不是所有的设定都执行。为此,我们打了一个擦边球。在window.onload里设定了一个command方法。每一个webpart仅仅扩充其WebForm_DoCallback到ajaxcommands 变量。这样,起码解决了本例中的问题。应该算得上一个好办法吧。
最后,contentloader字符串也包括了filldiv方法,用于设定div中的回调所返回的html内容。

最后一步,在我们的类的OnLoad 方法中将脚本注册到页面中。我们只需要在一个页面里有一个contentloader javascript脚本。所以,我们在注册前先判断是否已经被页面中其他的WebPart通过脚本管理器注册了。

剩下的事儿就是实现IcallbackEventHandler接口所需要的两个方法。

string ICallbackEventHandler.GetCallbackResult()
{
return this .ajaxdata;
}

void ICallbackEventHandler.RaiseCallbackEvent( string eventArgument)
{
this .ajaxdata = " Somecrazymessagehere!<BR> " + this .ClientID;
}


RaiseCallbackEvent当客户端回调启动时将被调用。它是一个无返回值的方法,仅用于将GetCallbackResult方法需要的数据准备好。RaiseCallbackEvent方法是我们放置所有用于返回给webpart的render方法要显示内容的相关代码的地方。本例中我们只发送一条简单的信息给客户端。为了区分不同的WebPart实例确实做了各自的工作,我们在信息后加上了各自的ClientID

赶快动手实践一下吧,希望大家对使用客户端回调已经入门了。

相关文章:

  • python分段线性插值_[Python] 分段线性插值
  • 装机遇到的问题
  • 声学测试软件手机版_来了,小米手机的2019黑科技总结
  • 在Sql Server 中调用Jmail组件发送邮件
  • python处理音频的软件_Python音频操作工具PyAudio上手教程!
  • 在本机运行vbs, 让远程计算机启动一个程序
  • 机器学习cnn数据集_Scikit-Learn&More,用于机器学习的综合数据集生成
  • 转:任正非寄语2010:开放、妥协与灰度
  • mysql 日期函数_SQL Date 函数
  • Leo谈职场危机攻关
  • 什么相片可以两张弄成一张_小小相片满满的爱 instax SHARE SP-2惠普小印200轻评...
  • python面向对象设计俄罗斯方块_俄罗斯方块:Python实现
  • XML的四种解析器原理及性能比较
  • 阿里前端开发规范_俺们阿里云计算平台数加团队的校招开始喽~
  • python qt 按钮实现拖放_python GUI库图形界面开发之PyQt5拖放控件实例详解
  • go append函数以及写入
  • JavaScript实现分页效果
  • Linux gpio口使用方法
  • magento 货币换算
  • node入门
  • Objective-C 中关联引用的概念
  • Odoo domain写法及运用
  • Redux 中间件分析
  • scala基础语法(二)
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • TypeScript实现数据结构(一)栈,队列,链表
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 飞驰在Mesos的涡轮引擎上
  • 给初学者:JavaScript 中数组操作注意点
  • 浅谈web中前端模板引擎的使用
  • 微信小程序实战练习(仿五洲到家微信版)
  • 线性表及其算法(java实现)
  •  一套莫尔斯电报听写、翻译系统
  • 正则学习笔记
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • kubernetes资源对象--ingress
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​香农与信息论三大定律
  • # 数据结构
  • #Linux(Source Insight安装及工程建立)
  • #QT(一种朴素的计算器实现方法)
  • (1)svelte 教程:hello world
  • (2)空速传感器
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (十一)图像的罗伯特梯度锐化
  • (转)Linux整合apache和tomcat构建Web服务器
  • **《Linux/Unix系统编程手册》读书笔记24章**
  • .NET CORE Aws S3 使用
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET企业级应用架构设计系列之应用服务器