2010-08-16 9 views
0

J'ai rencontré un problème intéressant en utilisant des combos sous forme d'entrée. Mon formulaire contient des combos qui obtiennent des données des magasins json. Cela fonctionne bien lors de l'ajout d'un nouvel enregistrement, mais lorsque le formulaire est ouvert pour éditer un enregistrement existant, parfois l'identifiant apparaît comme sélectionné et non sa valeur (par exemple: il y en a 5 au lieu de "apple"). Je pense qu'il essaie de définir la valeur avant qu'il ne finisse de charger le combo.EXTJS Combo set problem

Je vérifie le nombre de magasins Combo et il renvoie zéro, ce qui signifie que la sélection est faite avant le chargement de la liste déroulante. je tente de définir la valeur en cas de charge et le feu événement select mais il ne fonctionne pas Il fonctionne bien quand je RESELECT un autre record dans ce magasin de temps est chargé

Je vois aussi ce fil, mais il ne donne pas de réponse possible ExtJS combo setting problem

Est-il possible de définir son texte?

Quelqu'un peut-il me donner la bonne réponse s'il vous plaît?

+1

Pourriez-vous s'il vous plaît poster un exemple de code de la zone de liste déroulante ainsi que la façon dont vous chargez/liez les valeurs renvoyées? –

Répondre

0

Utilisez-vous la méthode standard ExtJs setValue pour définir la valeur dans comboBox?

Vérifiez que vous définissez la valeur dans Ext.onReady (...);

Ou si vous chargez les valeurs par ajax, vous pouvez utiliser la méthode de mise à jour avec le rappel en 3ème paramètre (voir à http://dev.sencha.com/deploy/dev/docs/ -> ComboBox)

+0

onReady() ne suffit pas, car le magasin de la combobox n'a pas pu être chargé, même si le dom est prêt. – stivlo

0
var partyType_store = new Ext.data.Store(
{ 
    autoLoad: false, 
    autoDestroy: true, 

    // Note that I have renamed the web service proxy class 
    proxy: new Ext.data.HttpProxy({ 
     url: accounts.webService + '/GetType', 
     // ASP.NET WebService call in GET format 
     headers: { 
      'Content-type': 'application/json' 
     } 
    }), 

    fields: ['AccountTypeId', 'AccountTypeName'], 
    listeners { 
     load: function() { 
      Ext.getCmp('cmbPartyType').setValue(Ext.getCmp("txtId").getValue()); 
      Ext.getCmp('cmbPartyType').fireEvent("select"); 
     } 
    } 
}, 

// Combo is defined as 
{ 
    xtype: 'combo', 
    width: 150, 
    fieldLabel: 'Party Type', 
    name: 'PartyType', 
    id: 'accounts-cmbPartyType', 
    store: partyType_store, 
    displayField: 'PartyType', 
    valueField: 'PartyTypeId', 
    hiddenName: 'PartyTypeId', 
    mode: 'local', // important property when using store 
    typeAhead: true, 
    triggerAction: 'all', 
    selectOnFocus: true, 
    allowBlank: true, 
    forceSelection: true 
} 

je charge magasin combo sur l'événement dire cliquage événement

Ext.getCmp('cmbPartyType').getStore().load(); //this calls combo load event 

Il fonctionne très bien si je mets autoLoad = true en magasin Mais en fait, je ne veux pas charger un premier magasin pour réduire le trafic jusqu'à ce que le bouton de presse utilisateur

+0

Votre combo doit peut-être utiliser lazyRender = true. Je pense que vous devriez ajouter cette information à votre question originale et non comme une réponse (je peux me tromper, je suis très nouveau à SO). – Hugh

0

Pourquoi le mode est-il défini sur local au lieu de distant? Avez-vous utilisé FireBug pour vous assurer que les données envoyées à partir du service ASP sont correctement formatées?

Je suis un peu clair sur ce que vous attendez dans le magasin pour ces deux articles:
ValueField: « PartyTypeId » < - Est-ce un numéro ou ACODE? 5? DisplayField: 'PartyType' < - Est-ce un nombre ou un code? Pomme?

0

Je me bats avec ça depuis un moment et j'en ai finalement eu assez. Ajouter ce hack quelque part avant de charger des combos (ne doit pas être après le document prêt)

Ext.form.ComboBox.prototype.nativeSetValue = Ext.form.ComboBox.prototype.setValue; 
Ext.form.ComboBox.prototype.setValue=function(v){ 
    var combo = this; 
    if(this.valueField){ 
     var r = this.findRecord(this.valueField, v); 
     if (!r) { 
     var data = {} 
     data[this.valueField] = v; 
     this.store.load({ 
      params:data, 
      callback:function(){ 
       combo.nativeSetValue(v); 
      } 
     }) 

     } else return combo.nativeSetValue(v); 
    } else combo.nativeSetValue(v); 
} 

Cela essentiellement vérifier si votre valeur est dans votre magasin, et si ce n'est pas, faire un rappel avec ValueField = valeur, puis réessayez. Vous avez juste besoin de vous assurer que votre gestionnaire de serveur cherche "requête" pour les recherches et le champ clé pour les charges

0

Parfois, il semble l'ID, car il ya un race condition dans votre code. En fait, si le magasin a été chargé, il affichera la valeur d'affichage, sinon seulement l'identifiant.

J'ai testé cela dans mon propre code. Le magasin chargé beaucoup plus vite que l'appel Ajax pour récupérer la valeur d'initialisation (parce que j'ai memcached le premier appel). Comme le magasin a été chargé en premier, l'appel de setValue() avec l'ID a bien fonctionné.

Cependant, lorsque j'ai essayé de ralentir intentionnellement l'appel Ajax du magasin, seul l'identifiant était affiché et non la valeur d'affichage. J'ai donc vu des réponses disant que pour résoudre ce problème, vous devez utiliser autoLoad: true dans le ComboBox. L'utilisation de autoLoad est correcte, mais pas suffisante. Vous voulez être sûr que lorsque vous définissez la valeur, le magasin a déjà été chargé. Pour ce faire, il suffit de mettre un écouteur sur l'événement de chargement du magasin:

var dataStore = new Ext.data.JSonStore({ 
    url: 'your-url', 
    root: 'records', 
    fields: ['id', 'name'], 
    autoLoad: true, 
    listeners: { 
     load: function() { 
      app.initForm(); //here the name of the function setting form values 
     } 
}); 

Avec ce tout événement fonctionne bien dans les deux cas.

Pour éviter rechargeant les données lorsque ComboBox déclenche un événement nouveau chargement() après la première manche je vérifie si la valeur est définie dans app.initForm()

app.initForm = function() { 
    var customerField = Ext.getCmp('formName').getForm().findField('idCustomer'); 
    if (customerField.getValue !== '') { 
     return; //skipping init, form already filled 
    } 
    //Ajax Call here 
};