Плагин jQuery, контекст и setTimeout - PullRequest
1 голос
/ 03 января 2011

Я пишу плагин для jQuery, и у меня в голове беспорядок с проблемой контекста в javascript.

Это упрощенная версия моего плагина:

(function($){  

$.fn.myplugin = function(options){
    return new MyPlugin(this, options);
};


function MyPlugin(el, o )
{
    this.root    = el;
    this.input_box = el.find('#the_input');
    this.map = null;
    this.timeout = null;
    var self = this;

    self.input_box.keyup( function(){
    if( self.timeout!==null )
    {
       clearTimeout( self.timeout );
    }
    self.timeout = setTimeout( function(){
            self.search_address( self );
            }, 500 );
    });
}

MyPlugin.prototype = {

    search_address : function( context ){
          geocoder.geocode({'address':$('#direction').val()}, 
             function( results, status ){
              var lat = results[0].geometry.location.lat();
              var lng = results[0].geometry.location.lng();
              var latlng = new google.maps.LatLng( lat, lng );

              context.select_address( latlng, '' );                                   
    },

    select_address : function( latlng, text ){
        self.root.find('#url').val('http://maps.google.com/?q='+encodeURI($('#direccion').val())+'&ll='+coords.lat()+','+coords.lng()+'&ie=UTF8&oe=UTF8&z=18');
    }
};
})(jQuery);

Я читал, что setTimeout устанавливает контекст для глобального объекта, поэтому я сделал замыкание, чтобы иметь возможность передать контекст в функцию search_address.Это позволило мне вызвать select_address из функции обратного вызова в geocode функции, но этот обратный вызов вызывает select_address, и контекст снова нежелателен: self.root не найден.

Я полностьюПотерянный при обработке контекста, я думал, что, используя var self=this при инициализации "объекта", я бы избежал этих проблем ...

Я должен отметить, что select_address можно вызывать напрямую...

Ответы [ 2 ]

1 голос
/ 16 июня 2011

Я только что обнаружил что-то классное, что исправляет контекст SetTimeout в jQuery 1.4 +.

Вы можете использовать jQuery.proxy для решения проблемы контекста.

Вот мой код:


    Application = function()
    {
        this.AMethod = function(){};

        setTimeout($.proxy(this.AMethod,this), 100);


    }

По истечении времени ожидания выполняется Application.AMethod и, таким образом, поддерживается контекст «Application»

LE: В качестве альтернативы вы можете создать собственную прокси-функцию очень просто, если вы не хотите, чтобы ваш плагин ограничивался только jQuery 1.4+:


    function proxy(func, context)
    {
        return function(){ return func.apply(context, arguments);}
    }

1 голос
/ 03 января 2011

Используйте this в этой точке, чтобы обратиться к текущему контексту:

select_address : function( latlng, text ){
    this.root.find('#url').val('http://maps.google.com/?q='+encodeURI($('#direccion').val())+'&ll='+coords.lat()+','+coords.lng()+'&ie=UTF8&oe=UTF8&z=18');
}
...