[ExtJs] 控件初始化绑定事件 initialize 和 painted的区别

在使用ExtJs时,对于一些页面控件在初始化时希望绑定事件用于值修改时触发,通常会在控件初始化或控件展示时绑定。

一般常用的事件主要有initialize、added、beforeshow、activate 、painted。

initialize:

组件初始化后触发

 added:

组件被添加到容器后触发。

 beforeshow:

组件显示前触发(一般是浮动层(例如:弹窗或sheet)显示)

activate:

组件在容器中且被激活(显示)时触发

painted:

 每当组件的Elment在屏幕上实际可见(绘制)触发。

 来个demo演示下不同的效果:

先看下在构造组件时就为其一组件绑上默认值

{
    xtype: 'container',
    items: [{
        xtype: 'selectfield',
        label: '选择',
        value: 'A',
        options: ['A', 'B']
    }, {
        xtype: 'datefield',
        label: '日期',
        value: new Date()//直接构造时就指定默认值
    }],
    listeners: {
        initialize: function (sender) {
            sender.on({
                change: 'onInitBind',
                delegate: 'field', //限定field控件
                scope: sender,
                buffer: 20
            });
        },
        added: function (sender) {
            sender.on({
                change: 'onAddedBind',
                delegate: 'field', //限定field控件
                scope: sender,
                buffer: 20
            });
        },
        beforeshow: function (sender) {
            sender.on({
                change: 'onBeforeShowBind',
                delegate: 'field', //限定field控件
                scope: sender,
                buffer: 20
            });
        },
        activate: function (sender) {
            sender.on({
                change: 'onActivateBind',
                delegate: 'field', //限定field控件
                scope: sender,
                buffer: 20
            });
        },
        painted: function (sender) {
            sender.on({
                change: 'onPaintedBind',
                delegate: 'field', //限定field控件
                scope: sender,
                buffer: 20
            });
        },
    },

    onInitBind(field) {
        console.log('initialize绑定的change触发')
    },
    onAddedBind(field) {
        console.log('added绑定的change触发')
    },
    onBeforeShowBind(field) {
        console.log('beforeshow绑定的change触发')
    },
    onActivateBind(field) {
        console.log('activate绑定的change触发')
    },
    onPaintedBind(field) {
        console.log('painted绑定的change触发')
    }
}

此时当container被渲染时,任一事件都不会触发,除非手动更改selectfield或 datefield的值。

但是当我们把控件的初始值,借助viewModel里的值进行绑定时,问题就出现了

{
    xtype: 'container',
    viewModel: {
        data: {
            date: new Date()
        }
    },
    items: [{
        xtype: 'selectfield',
        label: '选择',
        value: 'A',
        options: ['A', 'B']
    }, {
        xtype: 'datefield',
        label: '日期',
        bind:{
            value:'{date}'
        }
        // value: new Date() 换成bind形式
    }],
}

此时当container 组件被展示出来时,控制台就会输出

除了painted 未被触发,其他的事件都被触发了。

主要由于:组件在实例化时控件都已渲染,但是viewModel的绑定是最后渲染的,所以控件在实例时 先完成了 initialize、added、beforeshow、activate 这些事件必要的条件。

然后控件再执行bind,那里面的子控件的值相当于由 null→ viewModel中的值,由此触发了对应的change事件。

painted事件则是在完整的绘制完毕后触发,完整的绘制就包括 viewModel的渲染及相应的bind处理

也许你可能说借助控制器 controller的 init 方法 ,其实控制器的init方法执行时间和 视图类控件的initialize事件触发时间,基本一致。

结论

当想对某一个容器里的部分子控件进行统一事件监听,又要给其赋予默认值时。

若是可以在其构造时就可以赋予默认值,那对其子控件的监听事件 放在initialize、added、beforeshow、activate 、painted皆可。

而如果采用的是定义类,或在其子控件渲染时动态赋值的,最好在painted事件绑定的方法里进行事件监听。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章