2009-11-24 3 views
2

J'essaye de construire l'application qui utilise la config simple passée par le serveur comme non-natif JSON (peut contenir des fonctions). Tout fonctionne bien jusqu'à présent, mais je suis curieux de savoir pourquoi PagingToolbar n'a pas une option pour utiliser le parent Grille magasin?Ext JS comment dire à PagingToolbar d'utiliser le stockage Grid parent?

J'ai essayé de mettre en magasin dans ma config comme ça, mais sans succès:

{... 
    store:Ext.StoreMgr.lookup('unique_store_id') 
} 

Est-il possible de le faire sans écrire des tonnes de javascript pour chaque vue de définir magasin, grille et d'autres articles en mon application ou au moins étendre les fonctionnalités de PaginationToolbar qui utilisent des options de l'objet parent?

MISE À JOUR, Voici court exemple de réponse du serveur (minified)

{ 
"xtype":"viewport", 
"layout":"border", 
"renderTo":Ext.getBody(), 
"autoShow":true, 
"id":"mainFrame", 
"defaults":{"split":true,"useSplitTips":true}, 
"items":[ 
    {"region":"center", 
    "xtype":"panel", 
    "layout":"fit", 
    "id":"content-area", 
    "items":{ 
     "id":"manager-panel", 
     "region":"center", 
     "xtype":"tabpanel", 
     "activeItem":0, 
     "items":[ 
      { 
       "xtype":"grid", 
       "id":"domain-grid", 
       "title":"Manage Domains", 
       "store":{ 
        "xtype":"arraystore", 
        "id":"domain-store", 
        "fields":[...], 
        "autoLoad":{"params":{"controller":"domain","view":"store"}}, 
        "url":"index.php" 
       }, 
       "tbar":[...], 
       "bbar":{ 
        "xtype":"paging", 
        "id":"domain-paging-toolbar", 
        "store":Ext.StoreMgr.lookup('domain-store') 
       }, 
       "columns":[...], 
       "selModel":new Ext.grid.RowSelectionModel({singleSelect:true}), 
       "stripeRows":true, 
       "height":350, 
       "loadMask":true, 
       "listeners":{ 
        "cellclick":activateDisabledButtons 
       } 
      } 
     ] 
    }, 
} 
] 
} 

Répondre

1

Une autre possibilité consiste à créer une sous-classe de GridPanel. Le constructeur de cette sous-classe peut examiner sa configuration donnée pour une configuration de PagingToolbar. S'il y en a un, instanciez le magasin (si nécessaire) et donnez-lui une référence à la configuration de PagingToolbar.

var MyGridPanel = Ext.extend(Ext.grid.GridPanel, { 
    constructor: function(cfg) { 
     if (cfg && cfg.store && cfg.bbar && cfg.bbar.xtype == 'paging' 
      && ! (cfg.bbar instanceof Ext.PagingToolbar && ! this.bbar.store 
     ) { 
      if (cfg.store.xtype && ! (cfg.store instanceof Ext.data.Store)) { 
       cfg.store = Ext.ComponentMgr.create(cfg.store); 
      } 

      cfg.bbar.store = cfg.store; 
     } 

     MyGridPanel.superclass.constructor.call(this, cfg); 
    } 
}); 

Exemple d'utilisation:

(new Ext.Window({ 
    width: 400, 
    height: 200, 
    layout: 'fit', 
    items: new MyGridPanel({ 
     store: { 
      xtype: 'arraystore', 
      fields: ['name', 'value'], 
      data: [ 
       ['name 1', 'value 1'], 
       ['name 2', 'value 2'] 
      ] 
     }, 
     columns: [ 
      { 
       dataIndex: 'name', 
       header: 'Name' 
      }, 
      { 
       dataIndex: 'value', 
       header: 'Value' 
      } 
     ], 
     bbar: { 
      xtype: 'paging', 
      pageSize: 25 
     } 
    }) 
})).show(); 

Une autre option consiste à utiliser createInterceptor pour appliquer le comportement ci-dessus au GridPanel directement:

Ext.grid.GridPanel.prototype.initComponent = 
    Ext.grid.GridPanel.prototype.initComponent.createInterceptor(function() { 
     if (this.store && this.bbar && this.bbar.xtype == 'paging' 
      && ! (this.bbar instanceof Ext.PagingToolbar) && ! this.bbar.store 
     ) { 
      if (this.store.xtype && ! (this.store instanceof Ext.data.Store)) { 
       this.store = Ext.ComponentMgr.create(this.store); 
      } 

      this.bbar.store = this.store; 
     } 
    }); 

Cela vous permettra de continuer à utiliser xtype: ' la grille'.

+0

Merci Owlness pour votre exemple, il pourrait aussi être une solution pour mon application. Est-il possible que je puisse écraser la configuration de la grille par défaut pour ajouter une validation supplémentaire pour la barre d'outils inférieure. – Nazariy

+0

Juste eu le plus grand DOH !!! moment. Je n'ai pas réalisé que vous pouvez mettre 'constructor' en tant que fonction dans l'objet passé à' Ext.extend'. Mais bien sûr, cela a du sens - le constructeur est juste une fonction sur le prototype et c'est là que toutes ces fonctions vont. Pendant tout ce temps, j'ai défini le constructeur comme une fonction et l'ai ensuite étendu. De cette façon, le code est beaucoup plus propre. –

+0

Quel type de validation supplémentaire demandez-vous, Nazariy? Toute manipulation que vous pourriez faire sur l'objet de configuration peut être effectuée dans le constructeur de l'exemple ci-dessus. Des modifications plus avancées peuvent également être appliquées en remplaçant d'autres méthodes ou en ajoutant des écouteurs d'événements. – owlness

1

La PagingToolbar raison est pas liée à la grille pour son magasin est qu'un PagingToolbar peut être utilisé avec tout composant qui prend en charge la pagination, pas seulement une grille, donc vous devez lui attribuer explicitement un magasin (qui pourrait être un magasin partagé que d'autres composants utilisent aussi).

Vous ne savez pas pourquoi votre code ne fonctionne pas - Je suppose que votre appel de recherche ne doit pas renvoyer une référence de magasin valide. Les deux possibilités évidentes sont que l'identifiant est faux, ou le magasin n'existe pas encore. Puisque vous n'avez posté aucun autre code, il est impossible de le dire au-delà. BTW, vous devriez être en mesure d'attribuer simplement la référence de magasin utilisée par votre grille directement à la barre d'outils sans avoir à faire une recherche, mais je suppose que cela dépend de la façon dont votre application est structurée.

+0

Je crée tous les éléments en transmettant la réponse du serveur à Ext.ComponentManager.create ({...}) avec le bon xtype. Ainsi, la plupart des éléments sont générés dynamiquement en fonction de l'objet retourné. Dans ce cas, le magasin défini dans l'objet Grid et si nécessaire peut être accédé via ID qui ne fonctionne pas dans mon cas, mais dans le stockage Firebug est accessible en utilisant ce StoreMgr.lookup – Nazariy

+0

Eh bien, si vous prétendez que l'appel StoreMgr renvoie un magasin valide ref, alors évidemment quelque chose d'autre est faux dans votre code. Comme vous n'avez posté aucun de vos autres codes de configuration ou d'application, il n'est pas possible de vous aider beaucoup plus loin. –

+0

est renvoyé ici réponse du serveur. – Nazariy

1

La configuration que vous avez est exécutée chaque fois que vous la définissez - généralement avant son instanciation. Donc Ext.StoreMgr.lookup('domain-store') arrivera avant que le constructeur de la grille a lieu.

C'est un peu un inconvénient de la façon dont ext js utilise les configurations statiques. Ce que vous devez faire est de passer outre, soit la grille, puis définissez programatically magasin de la barre d'outils ou utilisez peut-être beforeRender événement sur la grille comme ceci:

//...grid config 
listeners: {'beforerender' : {fn:function(){ this.getBottomToolbar().store = this.store }}} 

EDIT: Changé bbar à getBottomToolbar().

+0

Merci Igor pour votre exemple, mais cela ne fonctionne pas de cette façon, pour une raison quelconque, les éléments dans tbar et bbar ne sont pas disponibles directement via DOM. Comme je l'ai réussi à faire fonctionner via afterternender listerner et accéder à bbar via this.getBottomToolbar() – Nazariy

+0

Oui, ce serait juste, j'ai oublié que bbar est seulement une propriété de configuration. –

1

En fait sur 3.2.0 le listnere n'a pas fonctionné pour moi (il a rempli la grille, mais il ne m'a pas laissé changer la page).Le problème était que ext ne savait pas qu'il devait reconstruire la barre d'outils (comme vous venez de modifier une variable). Corriger ci-dessous: