フォーム(つまり、Ext.form.Panel)のanyフィールドが変更されるたびに起動する単一のイベントリスナーが欲しいのですが。ただし、Ext.form.Panelクラスは、これ自体のイベントを発生させません。
フォーム内のすべてのフィールドの「変更」イベントをリッスンする最良の方法は何ですか?
更新:コメントのヒントに基づいて3番目のオプションを追加しました(@innerJLに感謝します!)
わかりました。少なくとも 2つの非常に簡単な方法があるようです。
オプション1)フォームに追加される各フィールドに「変更」リスナーを追加します。
Ext.define('myapp.MyFormPanel', {
extend: 'Ext.form.Panel',
alias: 'myapp.MyFormPanel',
...
handleFieldChanged: function() {
// Do something
},
listeners: {
add: function(me, component, index) {
if( component.isFormField ) {
component.on('change', me.handleFieldChanged, me);
}
}
}
});
これには少なくとも1つの大きな欠点があります。一部のフィールドを他のコンテナに「ラップ」してから、それらのコンテナをフォームに追加すると、ネストされたフィールドは認識されません。つまり、コンポーネントを「詳細に」検索して、「変更」リスナーが必要なフォームフィールドが含まれているかどうかを確認することはありません。
オプション2)コンポーネントクエリを使用して、コンテナ内のフィールドから発生するすべての「変更」イベントをリッスンします。
Ext.define('myapp.MyController', {
extend: 'Ext.app.Controller',
...
init: function(application) {
me.control({
'[xtype="myapp.MyFormPanel"] field': {
change: function() {
// Do something
}
}
});
}
});
オプション3)フォームパネルの基礎となる「基本」フォーム(Ext.form.Basic)から発生する「dirtychange」をリッスンします。 重要:{trackResetOnLoad:true}がフォームパネルコンストラクターに渡されるようにして、「trackResetOnLoad」を有効にする必要があることを確認する必要があります。
Ext.define('myapp.MyFormPanel', {
extend: 'Ext.form.Panel',
alias: 'myapp.MyFormPanel',
constructor: function(config) {
config = config || {};
config.trackResetOnLoad = true;
me.callParent([config]);
me.getForm().on('dirtychange', function(form, isDirty) {
if( isDirty ) {
// Unsaved changes exist
}
else {
// NO unsaved changes exist
}
});
}
});
このアプローチは「最もスマート」です。フォームがいつ変更されたかを知ることができますが、ユーザーがフォームを元の状態に変更したかどうかも知ることができます。たとえば、テキストフィールドを「Foo」から「Bar」に変更すると、「dirtychange」イベントはisDirtyパラメータに対して「true」で発生します。ただし、ユーザーがフィールドbackを「Foo」に変更すると、「dirtychange」イベントが発生しますagain、isDirtyはfalseになります。
クリントの答えを補足したいと思います。もう1つのアプローチがあります(そして私はそれがあなたの問題に最適だと思います)。 change
リスナーをフォームのデフォルト設定に追加するだけです。
Ext.create('Ext.form.Panel', {
// ...
defaults: {
listeners: {
change: function(field, newVal, oldVal) {
//alert(newVal);
}
}
},
// ...
});