web-dev-qa-db-fra.com

Définir l'écouteur pour les événements de magasin dans un contrôleur

J'ai un contrôleur avec un magasin, un modèle et des vues.

Je dois écouter les événements beforesync et write du magasin dans le contrôleur, mais je ne sais pas comment définir ces écouteurs dans la fonction control- des contrôleurs.

Mon magasin ressemble à ceci: 

Ext.define('DT.store.UsersStore', {
    extend : 'Ext.data.Store',
    model : 'DT.model.User',
    id : 'myStore'
    autoSync : true,
    proxy : {
        type : 'ajax',
        api : {
            read : '/load_entries',
            update : '/update_entry'
        },
        reader : {
            type : 'json',
            root : 'user',
            successProperty : 'success'
        }
    }
});

Maintenant, j'essaie d'écouter les événements de mon contrôleur: 

...
init : function () {
    this.control({
        'myStore' : {
            beforesync : this.doSomething,
            write : this.doSomethingElse
        }
    });
},
...

Mon résultat attendu est que les fonctions seront exécutées, lorsque les événements sont déclenchés . Mais à ce stade, rien ne se produit lorsqu'ils sont déclenchés.

Comment puis-je obtenir que cela fonctionne?

28
Demnogonis

Votre chemin est possible mais ce n'est pas idéal, IMO. La meilleure façon consiste à utiliser le getter de magasin des contrôleurs. Dans votre cas, le code ressemblerait à ceci:

init : function () {
    // every controller has getters for its stores.
    // For store UsersStore getter would be getUsersStoreStore()
    this.getUsersStoreStore().addListener('write',this.finishedLoading, this);
    this.control({
        // widgets event handlers
    });
},
33
Molecular Man

Voici une syntaxe alternative à La réponse de Molecular Man .

Au lieu d'écrire,

init : function () {
    this.getUsersStoreStore().addListener('write',this.finishedLoading, this);
    this.control({
        // widgets event handlers
    });
},

Tu peux écrire

init : function () {
    this.getUsersStoreStore().on({
        write: this.finishedLoading,
        scope: this
    });
    this.control({
        // widgets event handlers
    });
},

Je pense que cette définition alternative se lit un peu mieux.

J'ai pris ceci d'un répond Izhaki m'a donné.

19
James McMahon

En ce qui concerne Extjs 4.2.1, votre manière initiale d'accéder à l'écouteur de magasin fonctionnerait réellement si vous utilisiez 'storeId' au lieu de l'id et la fonction 'listen' au lieu de 'control':

Ext.define('DT.store.UsersStore', {
    extend : 'Ext.data.Store',
    model : 'DT.model.User',
    storeId : 'myStore'
    ....

init : function () {
    this.listen({
        store: {
           '#myStore' : {
               beforesync : this.doSomething,
               ...
5
gambetti
Ext.define('Store', {
    model: 'Model',
    extend: 'Ext.data.Store',
    listeners: {
        'beforesync': function(){
            App.getController('somecontroller').onBeforeSync();
        }
    }
});

App - votre objet d'application La fonction onBeforeSync vous pouvez l'implémenter dans le contrôleur ... c'est le seul moyen d'attribuer l'événement au magasin tout en implémentant la logique dans le contrôleur. J'espère que ça aide

4
nscrob

Je l'ai résolu par moi-même.

J'ai ajouté l'auditeur manuellement dans l'événement render- de mon Panel

Ext.getCmp('userPanel').down('gridpanel').getStore().addListener('write',this.finishedLoading, this);

Merci pour l'aide @nscrob.

4
Demnogonis

J'espère que cet ajout aidera quelqu'un à ne pas perdre quelques heures à déboguer le noyau de la bibliothèque:

Relié à cette pratique consistant à accéder à l'instance Ext.data.Store à l'intérieur du contrôleur à l'aide de la méthode getter du contrôleur: par exemple. pour le "DT.store.UsersStore" ci-dessus, en utilisant this.getUsersStoreStore ():

faites attention que si le magasin est déjà associé dans une vue (par exemple, il a été déclaré comme propriété du magasin pour une définition de widget "UsersGrid" Grid.panel.Panel), cette méthode getter récupérera en fait une autre instance de la même classe Store et pas l'instance utilisée par le widget! La raison en est que l'ajout du magasin dans l'objet de configuration du constructeur est le suivant:

stores: ['UsersStore']

va en fait ajouter une nouvelle instance de magasin dans le hachage Ext.data.StoreManager.map donc - en supposant que 'UsersStore' soit le seul objet Store instancié jusqu'à présent - les clés de la carte ressemblent maintenant à:

0: "ext-empty-store"
1: "UsersStore"
2: "myStore"

Imaginez maintenant que vous souhaitiez lire de nouvelles données à l'aide de votre proxy store'a et afficher ces nouvelles données dans la "grille d'utilisateurs" et que vous souhaitiez toutes ces opérations lorsque l'utilisateur clique sur quelque chose. Ainsi, dans le contrôleur, vous aurez une méthode de gestion pour l'événement utilisateur. avec le code:

'user-selector' : {
    click: function(){
                     var oStoreReference = this.getUsersStoreStore();
                         oStoreReference.load( {params:{} });
            }
    }

Cet appel pour obtenir la référence sera traduit en interne dans this.getStore ('UsersStore') et renverra une référence au contrôleur généré - 1: "UsersStore" - et non - 2: "myStore" - comme on pouvait s'y attendre. De plus, l'appel load () chargera l'instance UsersStore avec les nouveaux modèles et cela ne sera pas reflété dans votre vue de grille (car la grille est liée et écoute les événements générés par l'instance de magasin "myStore").

Donc, mieux accéder au magasin par son itemId en utilisant la méthode générale getStore: this.getStore ('storeItemId')

1
Galileo_Galilei