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