现在的位置: 首页 > 综合 > 正文

Asp.Net Ajax 学习笔记12 基于Microsoft AJAX Library扩展客户端组件

2013年05月16日 ⁄ 综合 ⁄ 共 4403字 ⁄ 字号 评论关闭

1、C#中定义事件的方法

  • 第一种:逐个定义事件 

    public class WorkEventArgs : EventArgs
    {
        
    /* ...*/
    }


    public class SomeClass
    {
        
    public event EventHandler<WorkEventArgs> Work;
        
    protected void OnWork(WorkEventArgs e)
        
    {
            
    if (Work != null) Work(this, e);
        }

    }

    这是逐个定义事件的方式,其中EventHandler是也委托的范型,用来规定事件第二个参数的类型。这种方式在事件非常多的时候,会为每个事件生成一个委托对象。在事件没有使用到的情况下,会浪费内存。

  • 第二种:事件集合的方式
    public class SomeClass
    {
        
    static readonly object workEventKey = new object();
        
    protected EventHandlerList eventDelegates = new EventHandlerList();
        
    public event EventHandler<WorkEventArgs> Work
        
    {
            add
            
    {
                
    this.eventDelegates.AddHandler(workEventKey, value);
            }

            remove
            
    {
                
    this.eventDelegates.RemoveHandler(workEventKey, value);
            }

        }


        
    protected void OnWork(WorkEventArgs e)
        
    {
            EventHandler
    <WorkEventArgs> workEventDelegates =
            (EventHandler
    <WorkEventArgs>)this.eventDelegates[workEventKey];
            
    if (workEventDelegates != null) workEventDelegates(this, e);
        }

        
    //
    }

    在这个示例里用实例化了一个委托的列表,用workEventKey 作为事件的标识符。使用这种方法,使用一个事件才会在委托列表中加入一个委托,这样可以有效的节约内存。如果要添加一个事件,那么必须添加一个object对象作为标识符

2、Asp.Net Ajax里面的事件

Asp.Net Ajax事件的定义与第二种差不多

  • 定义委托List

    Demo.MyClass = function()
    {
        
    this._events = new Sys.EventHandlerList();
         
    // …
    }

    使用Sys.EnentHandlerList来实例化委托列表。

  • 定义事件的add和remove
    Demo.MyClass.prototype= 
    {
                    add_myEvent : 
    function(handler) 
                    
    {
                        
    this._events.addHandler("myEvent", handler);
                    }
    ,
                    remove_myEvent : 
    function(handler) 
                    
    {
                        
    this._events.removeHandler("myEvent", handler);
                    }
    ,
                    
    // ...
    }
            

    这里用字符串代替object作为委托的key

  • 添加触发事件的方法
    Demo.MyClass.prototype = 
    {
                    raiseMyEvent : 
    function(e) 
                    
    {
                        
    var handler = this._events.getHandler("myEvent");
                        
    if (handler) 
                        
    {
                            handler(
    this, e);
                        }

                    }

    }

    通过使用委托(事件)列表的getHandler方法得到这个事件的委托,然后抛出这个事件。注意,要抛出空参数可以使用Sys.EventArgs.Empty来表示e为一个空参数

3、继承时需要注意的问题

在Asp.Net Ajax中toLocaleString, valueOf, hasOwnProperty等方法都无法继承。通过重写Type的resolveInheritance方法解决

<script language="javascript" type="text/javascript">
    
//重写TyperesolveInheritance方法,就是解决继承的方法
    Type.prototype.resolveInheritance = function Type$resolveInheritance() 
    
{
        
if (arguments.length !== 0throw 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];
                
                
//如果memberValue存在,就是基类的方法存在,并且不等于所有类的基类Object的
                //的这个方法
                if (memberValue != Object.prototype[memberName])
                
{
                    
//将基类的这个方法付给子类,那么子类就继承了基类的这个方法
                    this.prototype[memberName] = memberValue;
                }

            }

            
            
delete this.__basePrototypePending;
        }

    }

</script>

不要在基类的构造函数中写toString方法

Demo.Parent = function()
{
    
// Incorrect
    this.toString = function()
    
{
        
return Object.getTypeName(this);
    }

}

这样做为什么不行,因为你在派生类定义一个toString方法是无法覆盖基类的toString的方法的,这违背了继承的原则。

3、修改已有类型

  • 添加某个类的成员直接可以在他的prototype上添加方法
  • 修改某个成员需要先备份修改等方法,然后定义同名方法
    var p = Demo.Employee.prototype;
    p._old_calculateSalary 
    = p._calculateSalary;
    p._calculateSalary 
    = function()
    {
        
    return this._old_calculateSalary() + (this.get_year() - 1* 2000;
    }

    这样做的缺点是修改基类的方法无法影响子类的方法。

抱歉!评论已关闭.