2010-10-05 120 views
2

我在这种情况下无法理解'this'的范围。我可以调用这些函数中的每一个,如:this.startTracking();从时间跟踪器切换对象中。但是,当我尝试执行代码时:Drupal.timeTracker.prototype.stopTracking();它失去了所有变量的范围,我的GET请求变得不确定。我怎样才能关闭stopTracking()onbeforeunload?Javascript中的变量范围

Drupal.behaviors.dynamicTimeTracker = function (context) { 
    $('form.node-time-tracker', context).each(function() { 
    new Drupal.timeTracker(this); 
    }); 
}; 

/** 
* A time tracker switch object 
*/ 
Drupal.timeTracker = function (form) { 
    var tracker = this; 
    this.form = form; 
    this.nid = $('#'+ form.id +' input[name="nid"]').attr('value'); 
    this.uid = $('#'+ form.id +' input[name="uid"]').attr('value'); 
    this.button = $('#'+ form.id +' input[type="submit"]'); 
    this.url = Drupal.settings.time_tracker.url + '/' + this.nid + '/' + this.uid; 
    this.counter = $('#'+ form.id +' .counter'); 

    this.initialize(); // TODO: make sure this function is called regularly to make sure trackers are in synch 
    this.startTracking(); 
    $(window).bind('beforeunload', function() { 
    Drupal.timeTracker.prototype.stopTracking(); // need help here 
    }); 
}; 

/** 
* Initialize the time tracker 
*/ 
Drupal.timeTracker.prototype.initialize = function() { 
    var tracker = this; 

    $.ajax({ 
    type: "GET", 
    url: tracker.url, 
    dataType: 'json', 
    success: function (status) { 
     $(tracker.counter).countdown({compact:true, since:-status['time']}).countdown('resume'); 

     if (status['status'] == 'ongoing') { 
     $(tracker.button).toggle(
      function() { 
      tracker.stopTracking(); 
      return false; 
      }, 
      function() { 
      tracker.startTracking(); 
      return false; 
      } 
     ); 
     $(tracker.counter).countdown('resume'); 
     $(tracker.button).val(Drupal.t('Stop')); 
     $(tracker.form).removeClass('node-time-tracker-start').addClass('node-time-tracker-stop'); 
     } 
     else { 
     $(tracker.button).toggle(
      function() { 
      tracker.startTracking(); 
      return false; 
      }, 
      function() { 
      tracker.stopTracking(); 
      return false; 
      } 
     ); 
     $(tracker.counter).countdown('pause'); 
     $(tracker.button).val(Drupal.t('Start')); 
     $(tracker.form).removeClass('node-time-tracker-stop').addClass('node-time-tracker-start'); 
     } 
    }, 
    error: function (xmlhttp) { 
     alert(Drupal.ahahError(xmlhttp, tracker.startURL)); 
    } 
    }); 
}; 

/** 
* Starts time tracking 
*/ 
Drupal.timeTracker.prototype.startTracking = function() { 
    var tracker = this; 

    // Ajax GET request for starting time tracker 
    $.ajax({ 
    type: "GET", 
    url: tracker.url + '/start', 
    dataType: 'json', 
    success: function (status) { 
     $(tracker.counter).countdown('change', {since: -status['time']}).countdown('resume'); 
     $(tracker.button).val(Drupal.t('Stop')); 
     $(tracker.form).removeClass('node-time-tracker-start').addClass('node-time-tracker-stop'); 
    }, 
    error: function (xmlhttp) { 
     alert(Drupal.ahahError(xmlhttp, tracker.startURL)); 
    } 
    }); 
}; 

/** 
* Stops time tracking 
*/ 
Drupal.timeTracker.prototype.stopTracking = function() { 
    var tracker = this; 

    // Ajax GET request for stopping time tracker 
    $.ajax({ 
    type: "GET", 
    url: tracker.url + '/stop', 
    dataType: 'json', 
    success: function (status) { 
     $(tracker.counter).countdown('change', {since: -status['time']}).countdown('pause'); 
     $(tracker.button).val(Drupal.t('Start')); 
     $(tracker.form).removeClass('node-time-tracker-stop').addClass('node-time-tracker-start'); 
    }, 
    error: function (xmlhttp) { 
     alert(Drupal.ahahError(xmlhttp, tracker.startURL)); 
    } 
    }); 
}; 

回答

1

我就拿出一个小片段:

this.startTracking(); 
$(window).bind('beforeunload', function() { 
    // this is defined by the above function definition 
    tracker.stopTracking(); 
}); 

您的问题是,当你创建绑定功能,this里面,将参考$(window),所以你需要创建这个副本,以便能够在这个新功能中引用它。

+0

谢谢你,那完全正确......我感谢你的帮助! – plunder 2010-10-05 13:50:59

0

googletorp的答案应该工作,但只是一个快速注:

我相信你所遇到的问题是因为你试图拨打:

Drupal.timeTracker.prototype.stopTracking(); 

相反,我认为它应该是是:

Drupal.timeTracker.stopTracking(); 

我不认为你应该在原型上调用函数,而是在你修改了原型的对象上。

+0

我确实尝试过这个,Firebug告诉我我的函数未定义 – plunder 2010-10-05 14:00:03

+0

有趣......我想我还有更多要了解JS原型。 – netRealm 2010-10-05 14:34:55

+0

在实例化对象之前,您不会继承原型(即,您需要创建'Drupal.timeTracker'实例才能在不通过原型对象的情况下使用'stopTracking') – xj9 2010-10-05 15:29:23

0

当您拨打new Drupal.timeTracker(this)时,它会创建一个新对象。该对象继承自Drupal.timeTracker.prototype。在该对象的方法内部,this被设置为对象本身。 Drupal.timeTracker.prototype不是对象,而仅仅是可以形成对象的新实例的模板;就像一个饼干刀,吃起来不是很好。最重要的是,你的实际计时器的内部状态不存在于那里。

当您致电Drupal.timeTracker.prototype.stopTracking时,它将在模板上调用,而不是实际的对象。如果你打电话tracker.stopTracking(),你会没事的。您不能拨打this.stopTracking(),因为当您要拨打stopTracking时,您处于onbeforeunload的事件处理程序中,因此您的this将是window对象。