2011-05-11 3 views
24

Je migre mon application de la version ExtJs 3 vers la version 4. J'ai plusieurs comboboxes sur mon formPanel, et précédemment j'ai utilisé hiddenName et tout ce stuff pour soumettre valueField au lieu de displayField.Extjs 4 valeur par défaut de la zone de liste déroulante

Toute mon adaptation fonctionne correctement (champ de valeur IS soumis), mais je ne peux pas définir les valeurs par défaut pour les zones de liste déroulantes, elles sont affichées comme vides après le chargement de la page. Auparavant, je l'ai fait juste en spécifiant le paramètre 'value' dans config. Y at-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 
}); 

config Combo:

{ 
    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 
} 
+0

S'il vous plaît publier quelques exemples de code pour nous de jeter un oeil à la question et une solution possible. –

+0

La question est précisément. Il n'y a pas de code requis même si je ne connais pas la réponse car je suis toujours coincé dans 3.x – sra

+0

Je suppose que c'est encore une question de chargement asynchrone de magasin et de combo, car si le magasin est défini en combo - ça marche bien . – BlackLine

Répondre

4

J'ai remarqué votre config Combo a 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. Se pourrait-il que cela confonde Ext afin qu'il ne trouve pas la valeur par défaut que vous essayez de définir? Essayez de supprimer queryMode afin qu'il soit par défaut à la valeur de «distant» (ou le définir explicitement.)

MISE À JOUR: Je migrais ma propre application de Ext3 à 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 problème principal est que la combobox n'a pas encore les données nécessaires au moment où elle est rendue. Le paramètre value lui donne une valeur mais il n'y a rien dans le magasin de données pour le faire correspondre, de sorte que le champ apparaît vide. J'ai découvert que la propriété autoLoad peut également spécifier une fonction de rappel à utiliser lorsque les données sont chargées. Voici ce que vous pouvez 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); 
     } 
    } 
    ... 
}) 
17

j'ai eu le même problème, a afaik à voir avec le rendu SelectList avant que les éléments sont ajoutés au magasin. J'ai essayé la méthode de rappel mentionnée ci-dessus sans aucune chance (devinez que cela devrait être un rappel sur la liste de sélection plutôt que sur le magasin).

J'ai ajouté cette ligne après l'ajout d'éléments au magasin et il fonctionne très bien:

Ext.getCmp('selectList').setValue(store.getAt('0').get('id')); 
+0

Merci, vous avez tout à fait raison –

0

Je parie que cela a à voir avec le temps que vous (de façon asynchrone) charger le combobox, et le temps que vous définissez la valeur de la combobox. Pour résoudre ce problème, il suffit de le faire:

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 
}); 

L'auto-chargement du magasin est désactivé. Maintenant, après vous avez placé votre ComboBox à un certain endroit - en utilisant le code dans votre message 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().

0

Essayez ce code:

var combo = new Ext.form.field.ComboBox({ 
    initialValue : something, 
    listeners: { 
     afterrender: function(t,o) { 
      t.value = t.initialValue;  
     } 
    } 
}) 
3

Vous pouvez mettre directement la logique dans le rappel, ou mettre en place 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 lecture, la valeur config/propriété sur votre 'combo' objet doit être défini sur une certaine valeur de sorte que la zone de liste déroulante obtient une valeur initiale. Vous avez déjà fait cela. La valeur "all" doit également être dans votre magasin avant de la définir comme valeur par défaut.

value: 'all' 

En outre, il est bon de définir une valeur pour la config ValueField, que vous avez déjà fait. Si vous ne le faites pas, l'écouteur select n'obtiendra pas la valeur correcte lors de l'appel de combo.getValue().

4

La meilleure façon de procéder est d'écouter l'événement afterrender, puis de 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);  
     } 
    } 
}); 
10

Ajout loading: true à la configuration de votre magasin va le corriger. Il semble y avoir un problème avec autoLoad: true et forceSelection: true. Ce petit hack fera croire à votre combobox que le magasin se charge même si la fonction de chargement n'a pas encore été déclenchée.

+0

@BlackLine Nice! Je voterais deux fois! Cette solution est simple et efficace. – leaf

+1

Pour ceux qui sont curieux de savoir pourquoi cela fonctionne, c'est parce que le [Constructeur Store] (http://docs.sencha.com/extjs/4.2.1/source/Store.html#Ext-data-Store-method- constructeur), diffère l'appel de chargement de 'autoLoad' de 1ms (voir à la fin du code du constructeur). Ainsi, la propriété 'loading' du magasin est définie sur' true' seulement après l'appel de la méthode combo 'setValue', et ainsi le magasin combo pense que le magasin est chargé et la valeur n'est pas valide (parce que le magasin est en fait vide). – rixo

+1

Je vous recommande de corriger ce système en remplaçant 'Ext.data.Store # constructor' pour définir' loading' à 'true' si' autoLoad' est également 'true'. Par exemple. 'Ext.définir (null, { \t override: 'Ext.data.Store', \t constructeur: function() { \t \t this.callParent (arguments); \t \t if (this.autoLoad) { \t \t \t this.loading = true; \t \t \t} }); ' – rixo

0

La spécification du paramètre 'value' dans la configuration est un moyen correct de définir les valeurs par défaut pour les zones de liste déroulantes.

Dans votre exemple, il suffit de définir forceSelection:false, cela fonctionnera correctement. Si vous souhaitez définir forceSelection:true, vous devez vous assurer que les données renvoyées à partir de votre magasin contiennent un élément 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, s'il vous plaît 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 ça marche!

0

Dans Extjs 5.0.1 cela devrait fonctionner, en combo config:

... 
editable: false, 
forceSelection: true, 
emptyText: '', 
Questions connexes