2010-10-26 9 views
6

Estoy tratando de escribir un widget jQuery siguiendo el modelo dado here. Aquí es una instantánea del widget:Cómo manejar eventos en los widgets de la interfaz de usuario de 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); 

Aquí el problema es con el alcance de "this" dentro del método _titleClick, dentro del método esto apunta al elemento de title. Pero necesito señalar el elemento widget.

Creo que una forma de hacerlo será utilizar una clase contenedora como

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

Es esta la mejor manera de resolver este problema o hay algún patrón general para resolver este problema?

Respuesta

3

me escribió un método de mi propia para resolver este problema

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

En su creación, init (o en algún lugar de la instancia) función hacer esto:

 _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)); 

     ... 

     }, 

Ahora defina su evento de objetos como este:

 _myevent: function(event) { 

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

Utilice el this._on() method para enlazar el controlador. Este método lo proporciona la fábrica de widgets jQuery UI y se asegurará de que dentro de la función del manejador, this siempre se refiera a la instancia 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

No sabía de esto. Creo que esta es la mejor opción si no necesita hacer referencia al elemento al que se hizo clic. – b01

0

definen alcance var = esta, y utilizar alcance en controlador de eventos.

_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

Otra forma de hacer lo mismo sin utilizar el cierre, es pasar el widget como una parte de los datos del evento, así:

// 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

Esto es lo que haría cuando necesite poder hacer referencia al elemento al que se hizo clic, y también obtener acceso a la instancia del widget. – b01

0

lo que solía ser a través de la jquery bind método ahora on es favorecido.

A partir de jQuery 1.7, el método .on() es el método preferido para asociar controladores de eventos a un documento. Para versiones anteriores, el método .bind() se usa para conectar un controlador de eventos directamente a los elementos . Los manejadores se adjuntan a los elementos actualmente seleccionados en el objeto jQuery, por lo que esos elementos deben existir en el punto donde se produce la llamada a .bind(). Para una vinculación de eventos más flexible, consulte la discusión de la delegación de eventos en .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` 
}, 
Cuestiones relacionadas