[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事件綁定的方法裏進行事件監聽。

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