javascript - ExtJS: Formulário Simples ignora formBind
Eu tenho um pequeno problema que está me deixando louco há dias. Eu tenho um painel de formulário:
Ext.define('EC.view.PasswordPanel', {
extend: 'Ext.form.Panel',
alias: 'widget.pwdpanel',
bodyPadding: 15,
initComponent: function() {
this.initialConfig = {url:'/password/'};
this.fieldDefaults = {
labelAlign: 'right',
labelWidth: 135,
msgTarget: 'side',
allowBlank: false,
inputType: 'password'
};
//this.listeners = {
//// circumvent broken formBind
//validitychange: function(comp, valid) {
//this.down('button').setDisabled(!valid);
//}};
this.buttons = [{
text: 'Change',
formBind: true,
scope: this,
handler: function() {
this.submit({
success: function(form, action) {
Ext.Msg.alert(
'Success',
'<p>Password change has been scheduled successfully.</p>' +
EC.DELAY_NOTICE);
form.reset();
},
failure: function(form, action) {
if ('result' in action &&
'msg' in action.result) {
Ext.Msg.alert('Error', action.result.msg);
}
}
});
}
}];
this.items = [ {
xtype: 'textfield',
name: 'pw_old',
fieldLabel: 'Old password'
}, {
xtype: 'textfield',
name: 'pw_new1',
id: 'pw_new1',
fieldLabel: 'New password',
minLength: 8,
maxLength: 16
}, {
xtype: 'textfield',
name: 'pw_new2',
fieldLabel: 'Confirm new password',
} ];
this.callParent(arguments);
}
});
que eu instancio uma aba de dentro de um TabPanel:
{
title: 'Change Password',
items: { xtype: 'pwdpanel' },
},
Agora, a validação funciona perfeitamente, mas o botão "Alterar" não é desativado enquanto o formulário não está válido. Para ser claro: quando eu o pressiono, ele não envia, mas eu sinto que ele deveria estar desativado?
Estou fazendo algo obviamente errado? Outro painel de formulário em uma segunda aba funciona perfeitamente.
Eu posso contornar o problema usando o listener que comentei, mas entendo que deveria funcionar sem ele.
P.S. Sinta-se à vontade para apontar quaisquer estupidezes/maus estilos, estou totalmente novo no ExtJS.
Resposta #1
É um bug claro do extjs porque até o próprio exemplo deles funciona da mesma forma.
No entanto, encontrei uma solução rápida - adicione as linhas a initComponent:
this.on('afterrender', function(me) {
delete me.form._boundItems;
});
Aqui está o violino.
ATUALIZAÇÃO
O bug foi corrigido na 4.0.7.
Resposta #2
Com certeza este é um bug do ExtJS, como você pode encontrar em Ext.form.Basic.getBoundItems. Esta função originalmente inicializa boundItems como um array vazio ([]) porque ela começa a consultar antes que os campos sejam renderizados. Então, aqui está a correção para este bug.
//Fix formBind
Ext.form.Basic.override({
getBoundItems: function() {
var boundItems = this._boundItems;
//here is the fix
if(this.owner.rendered) {
if (!boundItems) {
boundItems = this._boundItems = Ext.create('Ext.util.MixedCollection');
boundItems.addAll(this.owner.query('[formBind]'));
}
}
return boundItems;
}
});
Esta correção se aplica globalmente, então você não precisa sempre adicionar o manipulador 'afterrender' em cada formulário que você criar. Aqui está um exemplo de uso http://jsfiddle.net/gajahlemu/SY6WC/
