`
refurbish
  • 浏览: 27833 次
  • 性别: Icon_minigender_1
  • 来自: 福州
文章分类
社区版块
存档分类
最新评论

Ext 源码学习之 Observal:类

阅读更多
  Observable故明思义,就是观察者的意思,主要是事件的处理,在java设计模式中,有观察者这一设计模式.观察者的主要思路是,对于某一事件发生变化,能对该事件的变化
做出相应的处理.用代码来来说就是增加事件侦听,和侦听的处理机制.
    Observable类在定义时,代码如下:
if(this.listeners){
        this.on(this.listeners);
        delete this.listeners;
    }


    只是做了一个增加侦听的处理. on 是对方法 addListener 的定义.可以看一下 addListener方法做的事情:
   
    addListener : function(eventName, fn, scope, o){
        if(typeof eventName == "object"){
            o = eventName;
            for(var e in o){
                if(this.filterOptRe.test(e)){
                    continue;
                }
                if(typeof o[e] == "function"){
                    // shared options
                    this.addListener(e, o[e], o.scope,  o);
                }else{
                    // individual options
                    this.addListener(e, o[e].fn, o[e].scope, o[e]);
                }
            }
            return;
        }
        o = (!o || typeof o == "boolean") ? {} : o;
        eventName = eventName.toLowerCase();
        var ce = this.events[eventName] || true;
        if(typeof ce == "boolean"){
            ce = new Ext.util.Event(this, eventName);
            this.events[eventName] = ce;
        }
        ce.addListener(fn, scope, o);
    }


   该方法主要定义事件,并增加侦听到对应的事件中.其中涉及到Event类.Event类如下:
   Ext.util.Event = function(obj, name){
        this.name = name;
        this.obj = obj;
        this.listeners = [];
    };

   先定义事件的名称,对象,侦听列表,对原型重载:
    Ext.util.Event.prototype = {
        addListener : function(fn, scope, options){
            scope = scope || this.obj;
            if(!this.isListening(fn, scope)){
                var l = this.createListener(fn, scope, options);
                if(!this.firing){
                    this.listeners.push(l);
                }else{ // if we are currently firing this event, don't disturb the listener loop
                    this.listeners = this.listeners.slice(0);
                    this.listeners.push(l);
                }
            }
        },

        createListener : function(fn, scope, o){
            o = o || {};
            scope = scope || this.obj;
            var l = {fn: fn, scope: scope, options: o};
            var h = fn;
            if(o.delay){
                h = createDelayed(h, o, scope);
            }
            if(o.single){
                h = createSingle(h, this, fn, scope);
            }
            if(o.buffer){
                h = createBuffered(h, o, scope);
            }
            l.fireFn = h;
            return l;
        },

        findListener : function(fn, scope){
            scope = scope || this.obj;
            var ls = this.listeners;
            for(var i = 0, len = ls.length; i < len; i++){
                var l = ls[i];
                if(l.fn == fn && l.scope == scope){
                    return i;
                }
            }
            return -1;
        },

        isListening : function(fn, scope){
            return this.findListener(fn, scope) != -1;
        },

        removeListener : function(fn, scope){
            var index;
            if((index = this.findListener(fn, scope)) != -1){
                if(!this.firing){
                    this.listeners.splice(index, 1);
                }else{
                    this.listeners = this.listeners.slice(0);
                    this.listeners.splice(index, 1);
                }
                return true;
            }
            return false;
        },

        clearListeners : function(){
            this.listeners = [];
        },

        fire : function(){
            var ls = this.listeners, scope, len = ls.length;
            if(len > 0){
                this.firing = true;
                var args = Array.prototype.slice.call(arguments, 0);
                for(var i = 0; i < len; i++){
                    var l = ls[i];
                    if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
                        this.firing = false;
                        return false;
                    }
                }
                this.firing = false;
            }
            return true;
        }
    };


   对原型重载:主要有增加侦听,创建侦听,查找侦听,判断侦听是否存在,删除侦听,清除所有侦听,触发侦听七个主要方法.
  增加侦听:先判断侦听是否存在,如果已存在则不处理,如果不存在,则创建侦听,如果末触发则增加,如果正在触发则取触发队列进行增加.

        对于增加完侦听后,可以对事件侦听的触发,触发方法 fireEvent,其方法如下:
    fireEvent : function(){
        if(this.eventsSuspended !== true){
            var ce = this.events[arguments[0].toLowerCase()];
            if(typeof ce == "object"){
                return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
            }
        }
        return true;
    }

   传递两个参数,事件名称和数据.
    现在有了事件和侦听,还可以触发事件,可以写个例子应用一下.一个给一个员工修改姓名时,这时将触发一个事件,通知已经修改员工姓名,并把员工新旧名列出.
//定义一个人类
person = function(name) {
        person.superclass.constructor.call(arguments);
        this.name = name;
        this.addEvents("update");//增加侦听,可以放在外面处理
};


//扩展人类,让它继承Observable类
Ext.extend(person,Ext.util.Observable,{
    setName:function(name){
       this.name = name;
    },
    update : function(name){
            if(this.hasListener("update")){
                        this.fireEvent("update",{newName:name,oldName:this.name});//更新时处理
            }
        this.name = name;
    }
});

测试:
                    var p = new person("Jacky");
                    
                    p.on("update", function(args) {
                                alert(JSON.stringify(args));
                        });
                        
                        p.update("Andy");


这里可以看出触发了update的事件,而且可以针对一个事件,增加多个侦听.如可以再增加侦中:
                        p.on("update", function(args) {
                                alert("SHIT");
                        });

这样设置后,在触发完事件后执行第一个侦听后,会再执行另一个侦听.如果这里修改第一个侦听返回return false时,则不再往下执行其它侦听.可看源码中event事件的fire方法:
                    if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
                        this.firing = false;
                        return false;
                    }

对于一个简单的Observable类的继承设计的总结:首先是先注册一个事件,会把这个事件写入到Observable里的全局event来增加ext.util.event实例.完成后要进行实例的侦听.这个可以放在实例对象后进行处理.增加侦听时,只是对应的把这些函数,入参等信息增加到方法中.最后进行fire事件,在fire时把原来保存在event中(event只是一个{}).里面保存了fn,scope,option这些信息,在fire时找到对应的listener后,进行调用.


其它Observable相关方法:
Ext.util.Observable.capture 对原有事件的catch
                        Ext.util.Observable.capture(p,function(fn,option){
                                alert(JSON.stringify(option));
                        }) ;

在触发前调用该事件.
分享到:
评论

相关推荐

    ext JS 源码和学习资料

    本压缩包包含EXT JS的多个版本源码,如ext-3.2.0、ext3.3.1和ext4,以及对应的中文API文档和实用学习资料,对于想要深入理解EXT JS或提升EXT JS开发技能的人来说是宝贵的资源。 一、EXT JS 源码分析 EXT JS 的源码...

    ext学习资料 20篇详细学习笔记 初学者ext学习的文档

    这份"ext学习资料 20篇详细学习笔记 初学者ext学习的文档"是针对EXT初学者的一份宝贵资源,旨在帮助初学者快速入门EXT开发。 EXT的学习通常包括以下几个核心部分: 1. **EXT基础**:首先,你需要了解EXT的基本概念...

    ext源码分析

    10. 工具类和实用函数:EXT源码包含了大量的工具类和实用函数,如DOM操作、样式设置、字符串处理等,这些都是JavaScript开发中常用的功能。 通过以上分析,我们可以看出EXT源码的深度和广度,它是JavaScript UI开发...

    ext4文件系统源码

    EXT4,全称为Fourth Extended File System,是Linux操作系统中广泛使用的日志文件系统之一,它在2008年被引入Linux内核。EXT4在EXT3的基础上进行了多项改进,以提升性能、可靠性和可扩展性。这个源码包包含了EXT4...

    Ext JS源码分析与开发实例宝典光盘源码

    Ext JS源码分析与开发实例宝典光盘源码Ext JS源码分析与开发实例宝典光盘源码Ext JS源码分析与开发实例宝典光盘源码Ext JS源码分析与开发实例宝典光盘源码Ext JS源码分析与开发实例宝典光盘源码Ext JS源码分析与开发...

    ext 源码api 开发文档

    1. **源码分析**:EXT源码提供了深入学习EXT框架的机会。通过阅读源码,开发者可以了解EXT内部的工作机制,例如事件处理、组件创建、布局管理等。这对于调试、优化和扩展EXT应用至关重要。 2. **API文档**:EXT的...

    EXT4 源码+window下模拟ext2+linux_ext文件系统模拟

    EXT4是Linux操作系统中最常用的文件系统之一,它在2008年被引入到Linux内核,以替代较旧的EXT3系统。EXT4的主要改进包括更大的文件系统大小支持、更快的性能以及对大量小文件的优化处理。在这个压缩包中,你可能会...

    ext4环境搭建

    5. 学习和理解EXT4文件系统的数据结构和操作接口。 6. 编写和测试EXT4文件系统相关的驱动或模块。 对于EXT4的开发,这是一项复杂的任务,需要深厚的Linux内核知识和编程技能。开发者需要对文件系统的工作原理有深入...

    EXT dojochina Ext类静态方法.rar

    - `Ext.create()`: 这是EXT中最常用的静态方法之一,用于创建类的实例。你可以指定类名和配置选项,例如`Ext.create('Ext.window.Window', {title: 'Hello World'})`将创建一个新的窗口。 - `Ext.extend()`: 这个...

    Ext中文帮助文档(Ext常见界面源码,及类库方法详解)

    4. Ext.grid.GridPanel:表格组件的主要类,包含了数据绑定、列配置、行处理等功能。 5. Ext.layout.ContainerLayout:容器布局,定义了不同类型的布局策略,如Fit、Border、Table等。 三、常见界面代码示例 文档中...

    ext4-util源代码——制作make_ext4fs和simg2img工具

    同时,这两个工具的源代码也是学习ext4文件系统和Android存储系统原理的好资料,开发者可以通过阅读源码深入了解其工作原理。 总的来说,`ext4-utils`提供了制作和操作ext4文件系统的关键工具,对于Android开发者和...

    ext PPT,EXT 教程,EXT 中文帮助手册,EXT 中文手册,ext_教程(入门到精通),Ext技术程序文档大全.

    7. **EXT 教程.rar、EXT 中文帮助手册 .rar、ext_教程(入门到精通).rar、EXT 教程.rar**:这些都是压缩文件,包含了更详细的教程和帮助文档,可能包含视频教程、源代码示例等,需要解压后进行学习。 通过这些资源,...

    Ext的学习(三):数据添加完整操作

    在本篇博客“Ext的学习(三):数据添加完整操作”中,我们将深入探讨Ext JS库在数据管理和展示方面的高级用法。Ext JS是一个强大的JavaScript框架,用于构建富客户端Web应用程序,它提供了丰富的组件和数据管理功能。...

    ext 3.0源码+帮助文档chm

    在深入学习EXT 3.0源码时,建议先从核心类开始,例如Ext.Element(基础DOM操作)、Ext.Panel(基本组件)和Ext.data.Store(数据管理)。了解这些基础类的用法和实现原理后,再逐步探索更复杂的组件和功能,如Grid、...

    ext学习文档

    ### EXT学习文档知识点详解 #### 1. EXT简介 EXT是一个功能强大的JavaScript库,用于构建交互式的Web应用程序。它提供了一系列工具和API,使得开发者能够更容易地创建动态且丰富的用户界面。EXT支持多种浏览器,并...

    ext 3.2源码

    此外,通过源码学习,开发者能够更好地了解EXT的扩展机制,从而创建自定义组件和插件,满足特定项目需求。 总结来说,EXT 3.2的源码是一本生动的教科书,涵盖了前端开发的多个方面。通过深入研究,开发者可以提升...

    深入浅出ext js源码

    这种实例化的学习有助于将理论知识转化为实际操作,加深对EXT JS源码的理解。 在深入研究EXT JS源码时,我们可以关注以下几个方面: 1. **组件体系**:EXT JS的组件模型是其强大之处,理解组件的生命周期、渲染...

    ext2.0项目源代码供大家学习ext使用

    通过分析这个EXT 2.0项目源代码,开发者可以学习如何组织EXT应用程序的结构,如何利用EXT的API创建组件,如何处理数据交互,以及如何实现特定的功能。对于想要提升EXT编程技能或者希望理解EXT内部机制的人来说,这是...

    EXT3.3学习文档

    EXT3,全称为“Third Extended File System”,是Linux系统中广泛使用的日志文件系统之一,尤其在早期的发行版中非常常见。EXT3.3作为其一个更新版本,可能包含了一些性能优化、错误修复或者新功能的添加。 EXT3...

    ext4.2学习之路

    ### ext4.2学习之路:深入理解Ext JS 4.2框架 #### 一、Ext JS 4.2概述 Ext JS是一款强大的企业级富客户端Web应用程序开发框架,基于JavaScript和HTML5技术,用于构建高性能的桌面和移动Web应用程序。Ext JS 4.2...

Global site tag (gtag.js) - Google Analytics