Je migre mon application de la version ExtJs 3 à 4. J'ai plusieurs zones de liste déroulante sur mon formPanel, et auparavant j'ai utilisé hiddenName et tout ça stuff pour soumettre valueField au lieu de displayField.
Toute mon adaptation fonctionne correctement (champ de valeur IS soumission), mais je ne peux pas définir les valeurs par défaut pour les zones de liste déroulante, elles sont affichées comme vides après le chargement de la page. Auparavant, je le faisais simplement en spécifiant le paramètre "valeur" dans la configuration. Y a-t-il des idées pour résoudre ce problème?
Mon code - Modèle et magasin:
Ext.define('idNamePair', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'name', type: 'string'}
]
});
var dirValuesStore = new Ext.data.Store({
model: 'idNamePair',
proxy: {
type: 'ajax',
url: '../filtervalues.json',
reader: {
type: 'json',
root: 'dir'
}
},
autoLoad: true
});
Configuration combinée:
{
triggerAction: 'all',
id: 'dir_id',
fieldLabel: 'Direction',
queryMode: 'local',
editable: false,
xtype: 'combo',
store : dirValuesStore,
displayField:'name',
valueField:'id',
value: 'all',
width: 250,
forceSelection:true
}
J'ai eu le même problème, afaik a à voir avec le rendu de la liste de sélection avant que les articles ne soient ajoutés au magasin. J'ai essayé la méthode de rappel mentionnée ci-dessus sans aucune chance (je suppose que ce devrait être un rappel sur la liste de sélection plutôt que sur le magasin).
J'ai ajouté cette ligne après avoir ajouté des articles au magasin et cela fonctionne bien:
Ext.getCmp('selectList').setValue(store.getAt('0').get('id'));
Ajouter loading: true
à votre configuration de magasin le corrigera. Il semble y avoir un problème avec autoLoad: true
et forceSelection: true
. Ce petit hack fera croire à votre zone de liste déroulante que le magasin se charge même si la fonction de chargement n'a pas encore été déclenchée.
La meilleure façon de procéder consiste à écouter l'événement afterrender
, puis à définir la valeur par défaut dans la fonction de rappel.
Voir ce code:
new Ext.form.field.ComboBox({
//This is our default value in the combobox config
defaultValue: 0,
listeners: {
//This event will fire when combobox rendered completely
afterrender: function() {
//So now we are going to set the combobox value here.
//I just simply used my default value in the combobox definition but it's possible to query from combobox store also.
//For example: store.getAt('0').get('id'); according to Brik's answer.
this.setValue(this.defaultValue);
}
}
});
J'ai remarqué que votre configuration combinée contient queryMode: 'local'
. Cette valeur est destinée à lorsque vos données sont stockées localement dans un tableau. Mais votre modèle utilise un proxy AJAX. Serait-ce possible que cela confonde Ext afin qu'il ne puisse pas trouver la valeur par défaut que vous essayez de définir? Essayez de supprimer queryMode
afin il prend par défaut la valeur de 'remote' (ou le définit explicitement.)
MISE À JOUR: Je migrais ma propre application d'Ext3 vers 4 juste après avoir publié ce qui précède, et j'ai rencontré exactement le même problème. Je suis sûr que queryMode
en fait partie, mais le principal problème est que la zone de liste déroulante n'a pas encore les données nécessaires au moment où elle est rendue. La définition de value
lui donne une valeur mais il n'y a rien dans le magasin de données pour le faire correspondre, donc le champ apparaît vide. J'ai découvert que la propriété autoLoad
peut également spécifier une fonction de rappel à utiliser lors du chargement des données. Voici ce que vous pourriez faire:
store: new Ext.data.Store({
model: 'MyModel',
autoLoad: {
scope: this,
callback: function() {
var comboBox = Ext.getCmp("MyComboBoxId");
var store = comboBox.store;
// set the value of the comboBox here
comboBox.setValue(blahBlahBlah);
}
}
...
})
Vous pouvez soit mettre la logique directement dans le rappel, soit configurer une fonction pour gérer tous les magasins.
var store1 = Ext.create('Ext.data.Store', {
...
autoLoad: {
callback: initData
}
});
var store2 = Ext.create('Ext.data.Store', {
...
autoLoad: {
callback: initData
}
});
var myComboStores = ['store1', 'store2']
function initData() {
var loaded = true;
Ext.each(myComboStores, function(storeId) {
var store = Ext.StoreManager.lookup(storeId);
if (store.isLoading()) {
loaded = false;
}
}
if(loaded) {
// do stuff with the data
}
}
=====================
Pour ceux qui lisent, la valeur config/property sur votre objet 'combo' doit être définie sur une certaine valeur de sorte que la zone de liste déroulante obtient une valeur initiale. Vous l'avez déjà fait. La valeur "tous" doit également être dans votre magasin avant de la définir comme valeur par défaut.
value: 'all'
Il est également recommandé de définir une valeur pour la configuration valueField , ce que vous avez déjà fait. Si vous ne le faites pas, l'écouteur de sélection n'obtiendra pas la valeur correcte lors de l'appel de combo.getValue ().
Je parie que cela a à voir avec le temps que vous chargez (de manière asynchrone) la zone de liste déroulante et le temps que vous définissez la valeur de la zone de liste déroulante. Pour surmonter ce problème, procédez simplement comme suit:
Ext.define('idNamePair', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'name', type: 'string'}
]
});
var dirValuesStore = new Ext.data.Store({
model: 'idNamePair',
proxy: {
type: 'ajax',
url: '../filtervalues.json',
reader: {
type: 'json',
root: 'dir'
}
},
autoLoad: false // set autoloading to false
});
Le chargement automatique du magasin est désactivé. Maintenant, après vous avez placé votre ComboBox à un certain endroit - en utilisant le code dans votre article de départ - vous chargez simplement le magasin manuellement: dirValuesStore.load();
.
C'est probablement après la configuration Ext.apply(this, {items: [..., {xtype: 'combo', ...}, ...]})
dans certains composants initComponent()
.
Essayez ce code:
var combo = new Ext.form.field.ComboBox({
initialValue : something,
listeners: {
afterrender: function(t,o ) {
t.value = t.initialValue;
}
}
})
La spécification du paramètre 'value' dans la configuration est une façon correcte de définir les valeurs par défaut pour les zones de liste déroulante.
Dans votre exemple, définissez simplement forceSelection:false
, cela fonctionnera bien.
Si vous souhaitez définir forceSelection:true
, vous devez vous assurer que les données renvoyées par votre boutique contiennent un article dont la valeur est égale à votre valeur par défaut ('all' dans ce cas). Sinon, ce sera un texte vide par défaut. Pour être plus clair, veuillez remplacer votre définition dirValuesStore
par ceci:
var dirValuesStore = Ext.create('Ext.data.Store', {
fields: ['id', 'name'],
data: [
{id: 'all', name: 'All'},
{id: '1', name: 'Name 1'},
{id: '2', name: 'Name 2'},
{id: '3', name: 'Name 3'},
{id: '4', name: 'Name 4'}
]
})
Vous verrez que ça marche!
Dans Extjs 5.0.1, cela devrait fonctionner, dans le combo de configuration:
...
editable: false,
forceSelection: true,
emptyText: '',