您的位置:首页 > 编程语言 > ASP

ASP.NET AJAX(7)_Microsoft AJAX Library扩展客户端组件

2011-10-19 15:43 567 查看
首先,延续上一讲的内容,谈一下客户端面向对象类型系统中事件的使用

在C#中定义的一种方式
publicclassWorkEventArgs:EventArgs
{
...
}

publicclassSomeClass
{
publiceventEventHandler<WorkEventArgs>Work;
protectedvoidOnWork(WorkEventArgse)
{
if(Work!=null)Work(this,e);
}
}

在MicrosoftAJAXLibrary中释放事件

定义EventHandlerList对象MyNamespace.MyClass=function(){this._events=newSys.EventHandlerList();}

添加add和remove事件
MyNamespace.MyClass.prototype=
{
add_myEvent:function(handler)
{
this._events.addHandler("myEvent",handler);
},
remove_myEvent:function(handler)
{
this._events.removeHandler("myEvent",handler);
},
raiseMyEvent:function(e)
{
varhandler=this._events.getHandler("myEvent");
if(handler)
{
handler(this.e);
}
}
}



一个定义和使用事件的示例
创建一个aspx页面,添加ScriptManager,以下是主要代码

<asp:ScriptManagerID="ScriptManager1"runat="server">
</asp:ScriptManager>

<scriptlanguage="javascript"type="text/javascript">
Type.registerNamespace("Demo");//注册一个命名空间
Demo.Firer=function(){//定义一个构造函数
//this._events=newSys.EventHandlerList();
this._events=null;//我们只是声明,需要的时候再创建它
}
Demo.Firer.prototype=//定义成员
{
_get_events:function(){//获得类的EventHandlerList
if(!this._events){//如果是NULL,则创建EventHandlerList对象
this._events=newSys.EventHandlerList();
}
returnthis._events;
},
add_fire:function(handler){
this._get_events().addHandler("fire",handler);
},
remove_fire:function(handler){
this._get_events().removeHandler("fire",handler);
},
raiseFire:function(e){
varhander=this._get_events().getHandler("fire");
if(hander){
hander(this,e);
}
},
fireAfter:function(seconds){
setTimeout(Function.createDelegate(this,this._timeoutCallback),seconds*1000);
},
_timeoutCallback:function(){
this.raiseFire(Sys.EventArgs.Empty);
}
}
Demo.Firer.registerClass("Demo.Firer");//注册这个类

functiontext()
{
varfirer=newDemo.Firer();
firer.add_fire(onFireHandler);
firer.fireAfter(2);
}

functiononFireHandler(sender,e)
{
alert("I'mfired!");
}
</script>

<inputtype="button"value="Text"onclick="text()"/>


示例很简单,点击按钮,等待两秒钟后,触发事件

继承时需要注意的问题

toString,toLocaleString,valueOf,hasOwnProperty无法被继承,如果我们定义一个类A继承至类B,而在类A中没有定义toString方法,而我们使用Bb=newB();b.toString();方法则只是输出当前的类名,这就是MicrosoftAJAXLibrary设计上的一个问题,也不能说是它的问题吧,可能微软有微软的想法,我没有跟上它的想法而已

一个解决toString无法被继承的问题的示例
<scriptlanguage="javascript"type="text/javascript">
Type.registerNamespace("Demo");
Demo.Parent=function(){}
Demo.Parent.prototype={
toString:function(){
returnObject.getTypeName(this);
}
}
Demo.Parent.registerClass("Demo.Parent");

Demo.Child=function(){
Demo.Child.initializeBase(this);
}
Demo.Child.prototype={}
Demo.Child.registerClass("Demo.Child",Demo.Parent);

functiontext(){
alert(newDemo.Parent()+"\n"+newDemo.Child());
}
</script>

<inputtype="button"value="Text"onclick="text()"/>


这时,如果我们点击按钮,按理说应该弹出"Demo.Parent\nDemo.Child",但是,试试上它弹出的是"Demo.Parent\n[objectObject]"

那么我们要解决这个问题,就需要做如下操作

1.找到MicrosoftAJAX.debug.js(通常路径为C:\ProgramFiles\MicrosoftASP.NET\ASP.NET2.0AJAXExtensions\v1.0.61025\MicrosoftAjaxLibrary\System.Web.Extensions\1.0.61025.0)

2.找到其中的Type.prototype.resolveInheritance这个方法

3.然后把它复制到页面代码的新建的一个<script>标记中

<scriptlanguage="javascript"type="text/javascript">
Type.prototype.resolveInheritance=functionType$resolveInheritance(){
if(arguments.length!==0)throwError.parameterCount();

if(this.__basePrototypePending){
varbaseType=this.__baseType;

baseType.resolveInheritance();

for(varmemberNameinbaseType.prototype){//遍历定义在父类的成员
varmemberValue=baseType.prototype[memberName];
if(!this.prototype[memberName]){//如果子类中没有同名的成员
this.prototype[memberName]=memberValue;//把父类的成员复制到子类中
}
}

//以下是我们自己添加的代码
vardontEnumMembers=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable"];//所有无法继承的方法名
for(vari=0;i<dontEnumMembers.length;i++){//遍历
varmemberName=dontEnumMembers[i];
if(this.prototype[memberName]!=Object.prototype[memberName]){//如果自己的类中已经定义了这个方法
continue;//不做以下操作,继续循环
}
varmemberValue=baseType.prototype[memberName];//得到父类的这个名字的方法
if(memberValue!=Object.prototype[memberName]){//判断是否有自己的实现
this.prototype[memberName]=memberValue;//把父类的对这个方法的实现,复制到子类
}
}
//添加的代码到此为止
deletethis.__basePrototypePending;
}
}
</script>


5,我们刷新页面,得到了我们预期的效果,这段代码应该是很实用的,修补了MicorsoftAJAXLibrary的一个问题(当然我不确定是不是真的算是设计上的问题)

扩展类型

MicrosoftAJAXLibrary提供了面向对象机制,可以用来扩展已有类型,优点是有一个标准的模式可用,缺点是工作量很大,并且并非真正的修改了类型

如何修改已有类型

修改某个类的prototype成员

为已有类型添加成员的操作

修改某成员的步骤(1.备份prototype成员,定义同名成员,并在合适的时候使用以前的成员)

优点:简单,容易实现

缺点:修改父类可能无法在子类上体现

一个扩展已有类型的示例
创建一个aspx页面

<asp:ScriptManagerID="s"runat="server"></asp:ScriptManager>
<scriptlanguage="javascript"type="text/javascript">
Type.registerNamespace("Demo");

Demo.Employee=function(name,year){
this._name=name;
this._year=year;
}
Demo.Employee.prototype=
{
get_name:function(){
returnthis._name;
},

get_year:function(){
returnthis._year;
},

_calculateSalary:function(){
return3000;
},

toString:function(){
returnthis._name+","+this._calculateSalary();
}
}
Demo.Employee.registerClass("Demo.Employee");

functiontext(){
alert(newDemo.Employee("Xiaoyaojian",5));
}
</script>

<scriptlanguage="javascript"type="text/javascript">
varp=Demo.Employee.prototype;//得到Employee的成员
p._old_calculateSalary=p._calculateSalary;//把父类的方法备份
p._calculateSalary=function(){//重新定义这个方法
returnthis._old_calculateSalary()+(this.get_year()-1)*2000;
}
</script>

<inputtype="button"value="Xiaoyaojian"onclick="text()"/>


演示,很简单,关键呢就在下面一个<script>标记里,我已经添加了注释,看懂应该不会有任何问题

这是一个对单独类的修改,那么如果有继承关系呢?往下看最后一个示例

<asp:ScriptManagerID="d"runat="server"></asp:ScriptManager>

<scriptlanguage="javascript"type="text/javascript">
Type.registerNamespace("Demo");
Demo.Parent=function(){}
Demo.Parent.prototype=
{
someMethod:function(){
returnalert("OriginalsomeMethod.");
}
}
Demo.Parent.registerClass("Demo.Parent");
Demo.Child=function(){
Demo.Child.initializeBase(this);
}
Demo.Child.prototype={}
Demo.Child.registerClass("Demo.Child",Demo.Parent);

//newDemo.Child();
Demo.Parent.prototype.someMethod=function(){
returnalert("I'vebeenmodified.");
}

functiontext(){
newDemo.Child().someMethod();
}
</script>

<inputtype="button"value="Xiaoyaojian"onclick="text()"/>

这时,我们点击按钮,就会看到我们修改的父类someMethod方法,也体现到了子类,而当我们把注释掉的newDemo.Child();打开,我们就会看到了我们非常不愿意看到的效果,也是我一开始提到的,对父类的修改可能不会体现在子类上,这就是一个“可能”,因为当我们创建一个Child对象的时候,它已经去解决继承的问题,把父类的成员复制到子类中,我们再去修改父类的方法,就无法体现在子类上啦

完活。貌似今天完成的比较早了,下午三点四十,前几篇都是在晚上十一点以后完成的,生日也过了,感冒也好了,我想着尽快把关于MicrosoftAJAXLibrary的这期写完,然后。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐