在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
首先,延续上一讲的内容,谈一下客户端面向对象类型系统中事件的使用 在C#中定义的一种方式public class WorkEventArgs:EventArgs { ... } public class SomeClass { public event EventHandler<WorkEventArgs> Work; protected void OnWork(WorkEventArgs e) { if(Work!=null)Work(this,e); } } 在Microsoft AJAX Library中释放事件
一个定义和使用事件的示例创建一个aspx页面,添加ScriptManager,以下是主要代码 <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <script language="javascript" type="text/javascript"> Type.registerNamespace("Demo");//注册一个命名空间 Demo.Firer = function() {//定义一个构造函数 //this._events = new Sys.EventHandlerList(); this._events = null;//我们只是声明,需要的时候再创建它 } Demo.Firer.prototype =//定义成员 { _get_events: function() {//获得类的EventHandlerList if (!this._events) {//如果是NULL,则创建EventHandlerList对象 this._events = new Sys.EventHandlerList(); } return this._events; }, add_fire: function(handler) { this._get_events().addHandler("fire", handler); }, remove_fire: function(handler) { this._get_events().removeHandler("fire", handler); }, raiseFire: function(e) { var hander = 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");//注册这个类 function text() { var firer=new Demo.Firer(); firer.add_fire(onFireHandler); firer.fireAfter(2); } function onFireHandler(sender,e) { alert("I'm fired!"); } </script> <input type="button" value="Text" onclick="text()" /> 示例很简单,点击按钮,等待两秒钟后,触发事件
继承时需要注意的问题toString,toLocaleString,valueOf,hasOwnProperty无法被继承,如果我们定义一个类A继承至类B,而在类A中没有定义toString方法,而我们使用B b=new B();b.toString();方法则只是输出当前的类名,这就是Microsoft AJAX Library设计上的一个问题,也不能说是它的问题吧,可能微软有微软的想法,我没有跟上它的想法而已 一个解决toString无法被继承的问题的示例<script language="javascript" type="text/javascript"> Type.registerNamespace("Demo"); Demo.Parent = function() { } Demo.Parent.prototype = { toString: function() { return Object.getTypeName(this); } } Demo.Parent.registerClass("Demo.Parent"); Demo.Child = function() { Demo.Child.initializeBase(this); } Demo.Child.prototype = {} Demo.Child.registerClass("Demo.Child", Demo.Parent); function text() { alert(new Demo.Parent()+"\n"+new Demo.Child()); } </script> <input type="button" value="Text" onclick="text()" />
这时,如果我们点击按钮,按理说应该弹出"Demo.Parent\nDemo.Child",但是,试试上它弹出的是"Demo.Parent\n[object Object]" 那么我们要解决这个问题,就需要做如下操作 1.找到MicrosoftAJAX.debug.js(通常路径为C:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary\System.Web.Extensions\1.0.61025.0) 2.找到其中的Type.prototype.resolveInheritance这个方法 3.然后把它复制到页面代码的新建的一个<script>标记中 <script language="javascript" type="text/javascript"> Type.prototype.resolveInheritance = function Type$resolveInheritance() { if (arguments.length !== 0) throw Error.parameterCount(); if (this.__basePrototypePending) { var baseType = this.__baseType; baseType.resolveInheritance(); for (var memberName in baseType.prototype) {//遍历定义在父类的成员 var memberValue = baseType.prototype[memberName]; if (!this.prototype[memberName]) {//如果子类中没有同名的成员 this.prototype[memberName] = memberValue;//把父类的成员复制到子类中 } } //以下是我们自己添加的代码 var dontEnumMembers = ["toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable"];//所有无法继承的方法名 for (var i = 0; i < dontEnumMembers.length; i++) {//遍历 var memberName = dontEnumMembers[i]; if (this.prototype[memberName] != Object.prototype[memberName]) {//如果自己的类中已经定义了这个方法 continue;//不做以下操作,继续循环 } var memberValue = baseType.prototype[memberName];//得到父类的这个名字的方法 if (memberValue != Object.prototype[memberName]) {//判断是否有自己的实现 this.prototype[memberName] = memberValue;//把父类的对这个方法的实现,复制到子类 } } //添加的代码到此为止 delete this.__basePrototypePending; } } </script>
5,我们刷新页面,得到了我们预期的效果,这段代码应该是很实用的,修补了Micorsoft AJAX Library的一个问题(当然我不确定是不是真的算是设计上的问题)
扩展类型
如何修改已有类型
一个扩展已有类型的示例创建一个aspx页面 <asp:ScriptManager ID="s" runat="server"></asp:ScriptManager> <script language="javascript" type="text/javascript"> Type.registerNamespace("Demo"); Demo.Employee = function(name, year) { this._name = name; this._year = year; } Demo.Employee.prototype = { get_name: function() { return this._name; }, get_year: function() { return this._year; }, _calculateSalary: function() { return 3000; }, toString: function() { return this._name + ", " + this._calculateSalary(); } } Demo.Employee.registerClass("Demo.Employee"); function text() { alert(new Demo.Employee("Xiaoyaojian", 5)); } </script> <script language="javascript" type="text/javascript"> var p = Demo.Employee.prototype;//得到Employee的成员 p._old_calculateSalary = p._calculateSalary;//把父类的方法备份 p._calculateSalary = function() {//重新定义这个方法 return this._old_calculateSalary() + (this.get_year() - 1) * 2000; } </script> <input type="button" value="Xiaoyaojian" onclick="text()" />
演示,很简单,关键呢就在下面一个<script>标记里,我已经添加了注释,看懂应该不会有任何问题 这是一个对单独类的修改,那么如果有继承关系呢?往下看 最后一个示例 <asp:ScriptManager ID="d" runat="server"></asp:ScriptManager> <script language="javascript" type="text/javascript"> Type.registerNamespace("Demo"); Demo.Parent = function() { } Demo.Parent.prototype = { someMethod: function() { return alert("Original someMethod."); } } Demo.Parent.registerClass("Demo.Parent"); Demo.Child = function() { Demo.Child.initializeBase(this); } Demo.Child.prototype = {} Demo.Child.registerClass("Demo.Child", Demo.Parent); //new Demo.Child(); Demo.Parent.prototype.someMethod = function() { return alert("I've been modified."); } function text() { new Demo.Child().someMethod(); } </script> <input type="button" value="Xiaoyaojian" onclick="text()" /> 这时,我们点击按钮,就会看到我们修改的父类someMethod方法,也体现到了子类,而当我们把注释掉的new Demo.Child();打开,我们就会看到了我们非常不愿意看到的效果,也是我一开始提到的,对父类的修改可能不会体现在子类上,这就是一个“可能”,因为当我们创建一个Child对象的时候,它已经去解决继承的问题,把父类的成员复制到子类中,我们再去修改父类的方法,就无法体现在子类上啦
完活。貌似今天完成的比较早了,下午三点四十,前几篇都是在晚上十一点以后完成的,生日也过了,感冒也好了,我想着尽快把关于Microsoft AJAX Library的这期写完,然后。。。。。 |
请发表评论