2009-09-07 8 views
0

Je me suis heurté à cela auparavant et j'ai besoin de l'aide de quelqu'un de plus intelligent que moi!Modèle de conception d'événement/classe (prototype)

Comment joindre un événement d'un élément à une méthode d'une classe? Plus précisément, la même classe? Y a-t-il un meilleur moyen? En utilisant une approche de style de widget Qt, j'ai essayé de créer des objets "widget" autonomes en javascript. J'utilise le framework javascript Prototype et construit mon widget en tant que classe. Puis, en utilisant Event.observe, j'ai essayé d'attacher l'événement à une méthode de la classe. Mais l'affectation d'événement délie la méthode affectée. Voici un exemple d'une table simple que je suis en train de construire qui a des en-têtes de colonnes cliquables:

Objectify.Grid.Table = Class.create({ 
    initialize: function(headers) { 
     this.columns = headers; 
     this.rows = []; 
    }, 
    addRow: function(GridData) { 
     var len = this.rows.push(GridData); 
     return len-1; 
    }, 
    getRow: function(rowIndex) { 
     return this.rows[rowIndex]; 
    }, 
    build: function(parent) { 
     this.mainTable = new Element('table',{'class':'Objectify-Grid'}); 
     $(parent).update(this.mainTable); 

     var tableBody = new Element('tbody',{}); 
     this.mainTable.update(tableBody); 

      var headerRow = new Element('tr',{'class':'Objectify-Grid-header-row'}); 
      tableBody.update(headerRow); 

       this.columns.each(function(val,id) { 
        var hcell = new Element('td',{'class':'Objectify-Grid-header-cell'}).update(val); 
        headerRow.insert(hcell); 
        // EVENT ASSIGNMENT // 
        hcell.observe('click',this.respondToClick); 
        ///////////////////// 
       }.bind(this)); 

      this.rows.each(function(GridData,id) { 
       var row = new Element('tr',{'class':'Objectify-Grid-row','id':'Objectify-Grid-row'+id}); 
       tableBody.insert(row); 

        this.columns.each(function(columnName,index) { 
         var cell = new Element('td',{'class':'Objectify-Grid-cell'}).update(GridData.getValue(columnName)); 
         row.insert(cell); 
        }); 

      }.bind(this)); 
    }, 
    // RECEIVING METHOD // 
    respondToClick: function(event) { 
     var columnName = event.element().innerHTML; 
     // "this" is no longer bound in this method 
     this.sortColumnAsc(columnName); // [ERROR] 
    } 
}); 

Répondre

3

Je pense que vous devriez faire ceci:

hcell.observe('click',this.respondToClick.bindAsEventListener(this)); 

et le deuxième argument de la méthode "each" est l'objet auquel lier la fonction, donc vous pouvez le faire:

array.each(someFunction, this); 

au lieu de

array.each(someFunction.bind(this)); 
+0

me ressemble – robjmills

+0

Merci Fabien, j'aurais du creuser un peu plus dans les docs avant de poster! http://www.prototypejs.org/api/event/observe – Scott

0

Je ne suis pas trop familier avec Prototype, mais qu'est-ce que this fait référence dans le gestionnaire d'événements respondToClick? Si je devais deviner, je dirais qu'il se référait à l'élément DOM cliqué, et non à l'instance d'objet que vous vouliez.

Peut-être que vous pouvez affecter la grille à une propriété de l'élément DOM et réutiliser cette propriété pendant la fonction respondToClick, comme dans:

myDOMElement.someProperty = grid; 

//and later 

this.somePropery.sortColumnAsc(columnName); 
+0

Merci Dandres, mais « ce » j'espérais renverrait à la classe que la méthode était une partie. – Scott

Questions connexes