2010-10-05 108 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對象。