Ext框架基础_笔记_02

  记录一下Ext的基础知识部分:

~~底层框架部分

~类的创建

Ext.define('demo.Demo',{  
    name:'Lingo',
    hello:function(){
        return 'Hello ' + this.name;
    }
});

  使用Ext.define来定义一个类,其中包含有两个字段。第一个字段是String类型,代表类名,这里是'demo.Demo';第二个字段是Object类型,后面{}括起来的部分都是,用来填写类的字段和函数。

  (demo.Demo比起传统的方式建立类,摆脱了命名空间的束缚,对字段的切分和命名空间的创建都包在了框架身上)

  想要使用申明的类创建对象可以:

var demo = new demo.Demo()

  也许是版本的问题,new创建对象,我这里会报错,于是修改为:

  (可能是和命名空间冲突了,换成demo1也可以使用new创建...)

var demo = Ext.create('demo.Demo');
console.log(demo.name);
alert(demo.hello());

~对象的继承

复制代码
Ext.define('demo.DemoWindow', {
    extend: 'Ext.Window',
    title: 'demo Header',
    initComponent: function(){
        Ext.apply(this, {
                items: [{
                html: 'panel1'
            },{
                html: 'panel2'
            }]
        });
        this.callParent();
    }
});
复制代码

  在类中添加extend关键字声明继承关系。上面继承了Ext自带的Window并进行了扩展,提供了头部的名称和两个子组件分别是panel1和panel2。

  Ext.apply()函数将一批属性批量复制给当前对象;

  this.callParent()函数实现对父类函数的快捷调用;

var demoWindow = Ext.create('demo.DemoWindow');
console.log(demoWindow.title);
demoWindow.show();

~多重继承

复制代码
Ext.define('demo.Demo', {
    name: 'Lingo',
    hello: function() {
        return 'Hello ' + this.name;
    }
});

Ext.define('demo.DemoPanel', {
    extend: 'Ext.Window',
    mixins: ['demo.Demo']
});
复制代码

  Ext.define()遵行单继承。这里为了实现多继承的功能,使用mixins关键字。

  mixins提出使用混入的方式实现了对多继承的支持。

var demoPanel = Ext.create('demo.DemoPanel');

console.log(demoPanel.name);
console.log(demoPanel.hello());
demoPanel.show();

~自动代码补充

  这里的补充是指Ext自动会根据配置自动生成对应的辅助功能属性,例如:

复制代码
// 1.
Ext.define('demo.DemoInstance', {
    config: {
        title: 'demo'
    }
});

// 2.
Ext.define('demo.DemoInstance', {
    title: 'demo',
    getTitle: function() {
        return this.title;
    },
    setTitle: function(title) {
        this.title = this.applyTitle(title) || title;
    },
    applyTitle: function(title) {}
});
复制代码

  1. 和2. 是等价的。可以观察到,例子一仅仅定义了一个参数,Ext就自动补充了对应的setter、getter以及applyTitle()方法。

  想要继续定制属性和设置规则可以重写applyTitle()函数来实现。

var demoInstance = Ext.create('demo.DemoInstance');
console.log(demoInstance.getTitle());
demoInstance.setTitle('demo2')
console.log(demoInstance.getTitle());

~另外还有俩

Ext.define('demo.DemoObject',{
    statics: {
        //静态成员
    },
    contructor: function(){
        //初始化操作
    }
})

  statics关键字可以设置静态成员(无需创建就可以直接调用的属性或者函数);

  constructor关键字可以自定义构造函数,以进行一些初始化操作;

~~统一组件模型

  在日常开发中,接触最多的还是各种组件和布局,so,后面的更加重要。

~Ext.Component

  Ext.Component是Ext中所有可视组件的父组件;

  组件最常用到的功能包含:

initComponent() 初始化
render() 渲染
show() 显示
hide() 隐藏

  作为基类,Ext.Component本身不包含任何格式,我们需要在使用时为他指定渲染的html内容,通过html参数传入;

复制代码
<script>
Ext.onReady(function() {

    var box = new Ext.Component({
        el: 'test',
        style: 'background-color:red;position:absolute;',
        pageX: 100,
        pageY: 50,
        width: 200,
        height: 150
    });
    box.render();
});
</script>
<div id="test" style="background-color: antiquewhite;">我是div</div>
复制代码

  这行代码演示了如何使用Ext.Component在页面定义位置和大小:

~Ext.Panel

  Ext.Panel直接继承Ext.Container。不同之处在于,Panel无需继承就可以直接使用。

floating  设置浮动
shadow 设置阴影
draggable 可拖放的
collapsible 可折叠的
复制代码
var panel = new Ext.Panel({
    el: 'test',
    title: '测试标题',
    floating: true,
    shadow: true,
    draggable: true,
    collapsible: true,
    html: '测试内容',
    pageX: 100,
    pageY: 50,
    width: 200,
    height: 150
});
panel.render();
复制代码

~Ext.Container

  Ext.Container也继承自Ext.Component,提供了两个参数:layoutitems

layout 指定当前组件的布局
items 指定当前组件中的所有子组件
xtype 简化配置和延迟布局中组件的初始化

xtype属性用法举例:

复制代码
new Ext.Viewport({
    layout: 'border',
    defaults: {
        collapsible: true, //支持该区域展开和折叠
        split: true, //支持用户拖放改变区域大小
        bodyStyle: 'padding:15px' //内边距
    },
    items: [
        new Ext.Panel({
            region: 'north',
            height: 80,
            html: '我是北边'
        }),
        new Ext.Panel({
            region: 'south',
            minSize: 75,
            maxSize: 250,
            height: 80,
            html: '我是南边'
        }),
        new Ext.Panel({
            region: 'west',
            width: 150,
            html: '我是西边'
        }),
        new Ext.Panel({
            region: 'east',
            width: 150,
            html: '我是东边'
        }),
        new Ext.Panel({
            region: 'center',
            html: '我是中间'
        })
    ]
});
复制代码

等价于:

复制代码
new Ext.Viewport({
    layout: 'border',
    defaults: {
        collapsible: true, //支持该区域展开和折叠
        split: true, //支持用户拖放改变区域大小
        bodyStyle: 'padding:15px' //内边距
    },
    items: [{
        xtype: 'panel',
        region: 'north',
        height: 80,
        html: '我是北边'
    }, {
        region: 'south',
        minSize: 75,
        maxSize: 250,
        height: 80,
        html: '我是南边'
    }, {
        region: 'west',
        width: 150,
        html: '我是西边'
    }, {
        region: 'east',
        width: 150,
        html: '我是东边'
    }, {
        region: 'center',
        html: '我是中间'
    }]
});
复制代码

  两种代码对比之下可以发现,使用xtype将会促成 延迟加载机制,所有子组件的生命周期都将会交给容器统一管理。对于没有设置xtype的组件,Ext会同意当作Ext.Panel使用,所以在使用Ext.Panel作为子组件时可以直接省略xtype参数。

  如果想要制作一个可以对自身包含的子组件进行布局的组件,那么就需要继承Ext.Container,他是一切可布局组件的父类;

~~Ext事件机制

  事件模型分为两种:自定义事件和浏览器事件;

~自定义事件

  Ext遵循一种树状事件模型,所有继承了Ext.util.Observable类的控件都可以支持事件。可以为继承了Ext.util.Observable的对象定义一些事件,然后为这些事件配置监听器。当某个事件被触发的时候,Ext会自动调用对应的监听器,这就是Ext的事件模型。

  1、创建Person类;

  (这里太坑了,版本不同,影响很大,这里使用的是4.2版本,所以需要添加一行代码,手动调用父类的构造函数..)

复制代码
//创建person类
Person = function(name) {
    this.name = name;
    this.addEvents('walk', "eat", "sleep");
    this.superclass.constructor.apply(this, arguments); //手动初始化父类构造函数
}
Ext.extend(Person, Ext.util.Observable, {
    info: function(event) {
        return this.name + 'is' + event + 'ing.';
    }
});
复制代码

  2、为person添加监听器

复制代码
var person = new Person('Lingo');
console.log(person.name); //Lingo
console.log(typeof(person)); //object

//添加事件监听器
person.on('walk', function() {
    Ext.Msg.alert('event', person.name + "在走啊走啊。");
});
person.on('eat', function(breakfast, lunch, supper) {
    Ext.Msg.alert('event', person.name + "要吃" + breakfast + ", " + lunch + "和" + supper + "。 ");
});
person.on('sleep', function(time) {
    Ext.Msg.alert('event', person.name + "从" + Ext.Date.format(time, "H") + "点开始睡觉啦。");
});
复制代码

  (on()是addListener()的简写形式)

  3、触发person事件

复制代码
//触发person事件
Ext.get('walk').on('click', function() {
    person.fireEvent('walk');
});
Ext.get('eat').on('click', function() {
    person.fireEvent('eat', '早餐', '中餐', '晚餐');
});
Ext.get('sleep').on('click', function() {
    person.fireEvent('sleep', new Date());
});
复制代码

  (使用fireEvent()会触发事件)

    <button id="walk">walk</button>
    <button id="eat">eat</button>
    <button id="sleep">sleep</button>

~浏览器事件

  浏览器事件就是传统意义上的鼠标单击、移动等事件,是由浏览器根据用户动作触发的,与页面元素紧密相关。Ext使用Ext.EventManager、Ext.EventObject和Ext.lib.Event对原生事件进行了封装,最后将一套统一的跨浏览器的事件通用接口展现给我们。

  HTML已经有了一套自己的事件绑定机制了,为什么还要重写一份呢??

  几乎每一个JS框架都会重写一份自己发事件绑定机制,原因很多,但是有一点很重要。那就是原生机制虽然简单但那时每次绑定事件只能绑定一个事件,如果同时绑定多个事件就会出现覆盖现象。但是,如果使用Ext绑定就不会出现覆盖问题,绑定的事件将会依次运行。

复制代码
Ext.onReady(function() {
    var test = Ext.get('test');
    test.on('click',function(){
        alert("handle1");
    });
    test.on('click',function(){
        alert("handle2");
    });
});
复制代码

  这段代码首先通过Ext.get('test')获得id,然后使用on绑定两个click事件,时间会依次执行,不会被覆盖。

~Ext.EventObjectImpl

  Ext.EventObjectImpl是对事件的封装,他将Ext自定义事件和浏览器事件结合到一起使用。首先,他封装了不同浏览器的事件处理函数,并为上层提供统一的功能接口。

getX()、getY() 获取对应的x、y坐标
getXY() 返回数组,getXY()[0]是x坐标,getXY()[1]是y坐标
getTarget() 返回事件的目标元素
on()、un() 绑定事件、事件清除
preventDefault() 取消浏览器对当前事件所执行的默认操作
stopPropagation() 停止事件传递
stopEvent() 停止一个事件
getRelatedTarget() 返回事件相关的HTML元素

  (书上给的是Ext.EventObjectImpl,不过经过查找4.2的文档没有发现这个,只看到了Ext.EventObject)

  Ext.EventObjectImpl(Ext.EventObject)定义了一系列功能键,举个例子:

复制代码
<script>
        Ext.onReady(function() {
            Ext.get('text').on('keypress', function(e) {
                if (e.charCode == Ext.EventObject.SPACE) {
                    Ext.Msg.alert('info', '空格');
                }
            });
        });
    </script>
    空格检测<input id="text" type="text">
复制代码

  同样,除了键盘,Ext.EventObject对Ext.lib.Event扩展的部分是对鼠标事件和按键事件的增强,它可以判断ALT、CTRL、SHIFT等功能键是否被按下,也可以使用altKey、ctrlKey和shiftKey判断单独被按下,也可以使用hasModifier()判断是否所有功能键被按下。

、 Ext.EventObject提供了另一种有趣的功能函数getWheelDelta()它可以获得鼠标滚动论的delta值。下面的例子,通过监听mousewheel事件,在滚轮转动时动态修改了test这个div的宽度:

复制代码
<script>
        Ext.onReady(function() {
            Ext.get(document.body).on('mousewheel', function(e) {
                var delta = e.getWheelDelta();
                var test = Ext.get('test');
                var width = test.getWidth();
                test.setWidth(width + delta * 500, true);
            });
        });
    </script>
    <div id="test" style="background-color: antiquewhite;">我是div</div>
复制代码

~Ext.util.Observable

  Ext.util.Observable在Ext事件中地位举足轻重,位于Ext组件的顶端,提供了事件处理的最基本功能。要实现一个可以处理事件的Ext组件,最直接的方法就是直接继承Ext.util.Observable。

  前面列举了addListener()/on()、removeListener/un()、addEvents()、fireEvent()这些函数的基本用法。下面是一些高级用法。

  addListener()/on()用于事件注册,可以使用复合式参数,如下:

复制代码
<script>
    Ext.onReady(function() {
        Ext.get('test').on('click', function() {
            Ext.Msg.alert("message", "Hello World");
        }, this, {
            single: true, //只作用一次
            delay: 2000, //延迟时间ms
            testId: 4
        });
    });
</script>

<button id="test">点我</button>
复制代码

  点击id为test的按钮,触发事件

   一共有四个参数,点击事件click,点击事件出发函数,作用域this,还有第四个就是复合参数了。

  另外还有一个参数buffer,如下:

复制代码
<script>
    Ext.onReady(function() {
        Ext.get('test').on('click', fn, this, {
            buffer: 1000,
            testId: 4
        });
    });
    fn = function(e, el, args) {
        alert("handle1");
        alert(args.testId);
    }
</script>

<button id="test">点我</button>
复制代码

  buffer和delay的区别就是,buffer会创建一个Ext.util.DelayTask对象,并把fn放入其中等待执行。在等待过程中,如果再次触发了事件,就会更新任务队列,这样就避免了fn的多次执行。

  我们在复合函数中定义了一个testId:4,它会被fn函数的第三个参数传递到函数中,并可以被args.testId来获得这个参数的值。

  除了复合参数,还可以使用on()一次定义多个事件监听器,如下:

复制代码
<script>
    Ext.onReady(function() {
        Ext.get('test').on({
            'click': {
                fn: fn
            },
            'mouseover': {
                fn: fn,
                single: true,
                delay: 100
            }
        })

    });
    var fn = function(e, el, args) {
        alert("handle1");
    }
</script>

<button id="test">点我</button>
复制代码

  加上了single:true,可以使得mouseover只执行一次,之后就可以继续click事件。

  Ext.util.Observable还有一个重要功能,那就是可以为某个事件添加拦截器,统一管理事件的触发。例如:

复制代码
<script>
    Ext.onReady(function() {
        Ext.get('capture1').on('click', function() {
            Ext.util.Observable.capture(person, function() {
                alert('下次小心点');
                return true;
            });
        }, this, {
            single: true //只执行一次
        });
        Ext.get('capture2').on('click', function() {
            Ext.util.Observable.capture(person, function() {
                alert('Game Over');
                return false;
            });
        });


        //创建person类
        Person = function(name) {
            this.name = name;
            this.addEvents('walk', "eat", "sleep");
            this.superclass.constructor.apply(this, arguments); //手动初始化父类构造函数
        }
        Ext.extend(Person, Ext.util.Observable, {
            info: function(event) {
                return this.name + 'is' + event + 'ing.';
            }
        });

        var person = new Person('Lingo');
        console.log(person.name); //Lingo
        console.log(typeof(person)); //object

        //添加事件监听器
        person.on('walk', function() {
            Ext.Msg.alert('event', person.name + "在走啊走啊。");
        });
        person.on('eat', function(breakfast, lunch, supper) {
            Ext.Msg.alert('event', person.name + "要吃" + breakfast + ", " + lunch + "和" + supper + "。 ");
        });
        person.on('sleep', function(time) {
            Ext.Msg.alert('event', person.name + "从" + Ext.Date.format(time, "H") + "点开始睡觉啦。");
        });

        //触发person事件
        Ext.get('walk').on('click', function() {
            person.fireEvent('walk');
        });
        Ext.get('eat').on('click', function() {
            person.fireEvent('eat', '早餐', '中餐', '晚餐');
        });
        Ext.get('sleep').on('click', function() {
            person.fireEvent('sleep', new Date());
        });
    });
</script>
<button id="capture1">留你半条命</button>
<button id="capture2">一棒子打死</button>

<button id="walk">walk</button>
<button id="eat">eat</button>
<button id="sleep">sleep</button>
拦截器:Ext.util.Observable.capture
复制代码

   点击capture1按钮的时候,拦截person的fireEvent()函数,弹出alert提示框,并返回true。也就是不会终止事件的进行。

  点击capture2按钮的时候,拦截person的fireEvent()函数,同样弹出alert提示框,但是返回的是false,这样就会终止事件。

  一个对象可以被设置多个capture拦截函数,这些拦截会变成一个处理链条,只要其中任何一个拦截函数返回false,就会终止处理过程。

  有拦截就会有反拦截,releaseCapture()函数就是capture()函数的反过程,它会一次性清除fireEvent()上的所有拦截函数,不过我们无法通过它定位某一个想要删除的拦截函数。一旦执行,就是全部失效,

  如果只想通过一次设置来暂停某一个对象中所有事件的发生,可以使用suspendEvents()函数(),如下:

Ext.get('suspendEvents').on('click', function() {
    person.suspendEvents();
})
Ext.get('resumeEvents').on('click', function() {
    person.resumeEvents();
})
<button id="suspendEvents">定身</button>
<button id="resumeEvents">解放</button>

  调用suspendEvents()之后,person中所有事件都会失效,只要再次调用resumeEvents()就会取消这个效果。

  这两个事件函数可以帮助我们统一管理某一个对象的事件。

 ~Ext.EventManager

  Ext.EventManager作为事件管理器,定义了一系列与事件处理相关的处理函数,常用的有onDocumentReady、onWindowResize和onTextResize,其中onDocumentReady就是常用到的Ext.onReady(),他会在页面文档渲染完毕之后但是还未下载的时候调用启动函数,也就是说,可以保证在onReady中的内容会在所有HTML元素都加载完成之后才执行,避免了找不到标签的情况,这个和有的人习惯把js下载最后的情况一致。

  onWindowResize()的作用是监听浏览器窗口大小改变,会提醒我们何时浏览器大小发生了改变,以及改变后的大小,如下:

<script>
    Ext.EventManager.onWindowResize(function(width, height) {
        alert('width:' + width + ',height:' + height);
    })
</script>

  这里就不需要加到onReady中,因为监听对象是window,页面一打开就存在了。其中只有两个参数,一个是width,一个是height。分别代表了窗口的宽和高。

 

posted @   无意生  阅读(616)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
Title

点击右上角即可分享
微信分享提示