2010-10-26 14 views
6

Sto provando a scrivere un widget jQuery seguendo il modello dato here. Ecco un'istantanea del widget:Come gestire gli eventi nei widget dell'interfaccia utente jQuery

(function ($) { 
    $.widget("ui.notification", { 
     _create: function() { 
      if (!this.element.hasClass("ntfn")) { 
       this.element.addClass("ntfn"); 
      } 

      this.elTitle = this.element.append("<div class='ntfn-title'>Notifications</div>"); 

      this.elTitle.click(this._titleClick) 
     }, 
     _titleClick: function() { 
      console.log(this); 
     } 
    }); 
})(jQuery); 

Qui il problema è con lo scopo di "questa" all'interno del metodo _titleClick, all'interno del metodo questa punta all'elemento title. Ma ho bisogno che indichi l'elemento widget.

Penso che un modo di farlo sarà quello di utilizzare una classe wrapper come

var that = this; 
this.elTitle.click(function() { 
    that._titleClick.apply(that, arguments); 
}); 

E 'questo il modo migliore per risolvere questo problema o c'è qualche schema generale per risolvere questo problema?

risposta

3

ho scritto un metodo mia per risolvere questo problema

_wrapCallback : function(callback) { 
    var scope = this; 
    return function(eventObject) { 
     callback.call(scope, this, eventObject); 
    }; 
} 
4

Si dovrebbe cercare di jQuery.proxy() http://api.jquery.com/jQuery.proxy/

el.bind('evenname', $.proxy(function() { 
    this.isMyScope.doSomething(); 
}, scope)); 
+0

Grazie. Questo e 'esattamente quello che stavo cercando. – jwanga

2

Nella tua creare, init (o da qualche parte nel vostro esempio) function do this:

 _create: function() { 

     ... 

     // Add events, you will notice a call to $.proxy in here. Without this, when using the 'this' 
     // property in the callback we will get the object clicked, e.g the tag holding the buttons image 
     // rather than this widgets class instance, the $.proxy call says, use this objects context for the the 'this' 
     // pointer in the event. Makes it super easy to call methods on this widget after the call. 
     $('#some_tag_reference').click($.proxy(this._myevent, this)); 

     ... 

     }, 

Definisci ora il tuo evento hander come questo:

 _myevent: function(event) { 

      // use the this ptr to access the instance of your widget 
      this.options.whatever; 
     }, 
15

Utilizzare il this._on() method per eseguire il binding dell'handler. Questo metodo è fornito dalla fabbrica di widget dell'interfaccia utente jQuery e si assicurerà che all'interno della funzione di gestore, this si riferisca sempre all'istanza del widget.

_create: function() { 
    ... 
    this._on(this.elTitle, { 
     click: "_titleClick" // Note: function name must be passed as a string! 
    }); 
}, 
_titleClick: function (event) { 
    console.log(this);  // 'this' is now the widget instance. 
}, 
+0

Non lo sapevo. Penso che questa sia la scelta migliore se non hai bisogno di fare riferimento all'elemento su cui è stato fatto clic. – b01

0

definire var scope = questo, e utilizzare portata nel gestore di eventi.

_create: function() {   
     var scope = this; 
     $(".btn-toggle", this.element).click(function() { 
      var panel = $(this).closest(".panel"); 
      $(this).toggleClass("collapsed"); 
      var collapsed = $(this).is(".collapsed"); 
      scope.showBrief(collapsed); 
     }); 
    }, 
0

Un altro modo per fare la stessa cosa senza l'utilizzo di chiusura, è quello di passare il widget come una parte dei dati degli eventi in questo modo:

// using click in jQuery version 1.4.3+. 
var eventData = { 'widget': this }; 

// this will attach a data object to the event, 
// which is passed as the first param to the callback. 
this.elTitle.click(eventData, this._titleClick); 

// Then in your click function, you can retrieve it like so: 
_titleClick: function (evt) { 
    // This will still equal the element. 
    console.log(this); 
    // But this will be the widget instance. 
    console.log(evt.data.widget); 
}; 
+0

Questo è ciò che farei quando devo essere in grado di fare riferimento all'elemento che è stato fatto clic e anche di accedere all'istanza del widget. – b01

0

E 'usato per essere attraverso il jquery bind metodo ora on è favorito.

A partire da jQuery 1.7, il metodo .on() è il metodo preferito per che associa i gestori di eventi a un documento. Per le versioni precedenti, il metodo .bind() viene utilizzato per allegare un gestore eventi direttamente agli elementi . I gestori sono collegati agli elementi attualmente selezionati in l'oggetto jQuery, quindi tali elementi devono esistere nel momento in cui si verifica la chiamata a .bind(). Per un binding di eventi più flessibile, consultare la discussione della delega degli eventi in .on() o .delegate().

_create: function() { 
    var that = this; 
    ... 
    elTitle.on("click", function (event) { 
      event.widget = that; // dynamically assign a ref (not necessary) 
      that._titleClick(event); 
    }); 
}, 
_titleClick: function (event) { 
    console.log(this);    // 'this' now refers to the widget instance. 
    console.log(event.widget);  // so does event.widget (not necessary) 
    console.log(event.target);  // the original element `elTitle` 
}, 
Problemi correlati