2012-08-14 66 views
0

我想教自己一些更好的JS開發實踐,所以我在JavaScript對象包裝器中編寫我的最新VLE小部件。對象中的變量範圍

var TutorGroupPoints = { 
    URL: 'http://staff.curriculum.local/frog/rewards.php', 
    CurrentUser: UWA.Environment.user.id, 
    Groups: { }, 
    Sorted: [ ], 

    init: function() { 
     /* retrieve all of the groups from Frog and store them in a variable */ 
     Frog.API.get('groups.getAll', 
     { 
      'onSuccess': function (data) { this.Groups = data; }, 
      'onError': function(err) { alert(err); } 
     });   
    }, 

    yearClick: function(year) { 
     alert(this.Groups); 

     for (var i = 0; i < this.Groups.length; i++) { 

      if (this.Groups[i].name.indexOf(year) == 0 && this.Groups[i].name.indexOf('/Tp') != -1) { 
       var arrayToPush = { 'id': this.Groups[i].id, 'name': this.Groups[i].name }; 
       this.Sorted.push(arrayToPush); 
      } 
     } 
    } 

}; 

widget.onLoad = function(){ 
    TutorGroupPoints.init(); 

    $('#nav li a').click(function() { 
     TutorGroupPoints.yearClick($(this).attr("id")); 
    }); 
} 

Frog.API調用檢索有關從我們的VLE(虛擬學習環境)的學生/員工信息。

我想要做的是將這些信息(在名爲data的變量中檢索到)存儲在類範圍變量中,以便與其他函數一起使用。

我想我會做到這一點通過聲明Groups變量早期然後用data = this.Groups,但是當我運行yearClick功能,this.Groups簡單地表現爲[object Object]其中data警報爲對象的負荷,即[object Object] [object Object] [object Object] [object Object] [object Object] [object Object] [object Object] [object Object] [object Object]

當我將Groups更改爲[ ]時,警報完全爲空。

因此,我猜這是一個範圍問題。如何將dataFrog.API調用中存儲到我可以與其他函數一起使用的變量中?以前我只是使用了函數,即'onSuccess': function (data) { someOtherFunction(data); },,但我不認爲這是一個很乾淨或實用的方法呢?

由於提前,

回答

1

這是一個常見的錯誤。作爲函數的成功回調會更改執行代碼的this上下文。因此,在您的回調中,this不再指向TutorGroupPoints對象。

要麼緩存到函數外側的外this參考...

init: function() { 
    var that = this; // <-- caching outer this 
    Frog.API.get('groups.getAll', { 
     'onSuccess': function (data) { that.Groups = data; }, 
     'onError': function(err) { alert(err); } 
    });   
} 

或結合一個拷貝的其經由閉合傳遞,在這種情況下的立即執行的功能

init: function() { 
    Frog.API.get('groups.getAll', { 
     'onSuccess': (function(that) { 
      return function (data) { that.Groups = data; } 
     })(this), // <-- passing reference to outer this 
     'onError': function(err) { alert(err); } 
    });   
} 
+0

哈哈,我們再次衝突;-) – Alnitak 2012-08-14 10:17:30

+0

不知道誰贏了這一次 - 他們都說「2分鐘前」。也許我們應該制定一個輪班輪換:) – Utkanos 2012-08-14 10:19:23

+1

FWIW,這個問題與呼叫是異步的無關。這是它使用內部函數的事實。 – Alnitak 2012-08-14 10:19:42

1

this變量是錯誤的青蛙回調裏面。使用此來代替:

init: function() { 
    var self = this; // reference for use inside closures 
    /* retrieve all of the groups from Frog and store them in a variable */ 
    Frog.API.get('groups.getAll', 
    { 
     'onSuccess': function (data) { self.Groups = data; }, 
     'onError': function(err) { alert(err); } 
    });   
} 

在任何時間的函數被調用時被提供的上下文(即this)。在你的回調裏面,你的this值可能是全球的window對象。使用緩存變量可確保原始(外部)this仍可在封閉內部訪問。