2012-04-21 19 views
3

我有一個事件將一個函數綁定到點擊。點擊在同一視圖中調用另一個功能。不幸的是,範圍不是正確的範圍。當我嘗試執行this.otherFunction()時,分配給click的函數與this.otherFunction()不在同一個作用域中。有沒有辦法通過其他函數()的範圍?如何將'this'傳遞給使用骨幹的事件?

initialize: function() { 
    this.render(); 

    if (joinedGoalList.get(this.model.id) != null) { 
    this.renderLeaveGoal(); 
    } else { 
    this.renderJoinGoal(); 
    } 
}, 

events: { 
    "keypress #goal-update": "createOnEnter", 
    "click #join-goal": "joinGoal", 
    "click #leave-goal": "leaveGoal", 
}, 

joinGoal: function() { 
    matches = joinedGoalList.where({id: this.model.get("id")}); 
    if (matches.length == 0) { 
    joinedGoalList.create({goal_id: this.model.get("id")}, {wait: true, success: function() { 
     var self = this; 
     self.renderLeaveGoal(); 
    }, error: function() { 
     console.log("error"); 
    }}); 
    } 
}, 

renderLeaveGoal: function() { 
    console.log("render leave goal"); 
    var template = _.template($("#leave-goal-template").html()); 
    console.log(template); 
    $("#toggle-goal-join").html(template()); 
}, 

這些都是在相同的看法。

編輯: 嗯,現在的問題是,我得到這個錯誤: Uncaught TypeError:Object [對象DOMWindow]沒有方法'renderLeaveGoal'。這似乎是我保存了錯誤的範圍?

+0

你可以添加一些你的代碼嗎? – ataddeini 2012-04-21 02:10:25

回答

5

標準的技術是做這樣的事情

var self = this; 

然後,你可以做

self.otherFunction(); 

在地方的

this.otherFunction(); 
+0

嗯,它在我的初始化函數中工作,當我嘗試再次調用函數時,它似乎不工作。 – egidra 2012-04-21 18:35:56

+0

鑑於丹M的解釋,這仍然是一個問題嗎? – deltanovember 2012-04-21 21:14:53

+0

是的,它仍然不起作用。我得出結論。我編輯了關於我的問題。 – egidra 2012-04-23 07:49:23

1

的功能附加到視圖,所以你需要將其從View對象中調用。

success: this.renderLeaveGoal 

在這種情況下,您不需要匿名函數,因爲視圖函數會自動綁定到視圖的上下文。

2

deltanovember的答案是正確的,但他沒有解釋爲什麼它是正確的,我覺得這一點很重要:

範圍是在Javascript中凌亂。我發現跟蹤它的最簡單方法是考慮,當東西會執行。如果一塊代碼立即執行,它可能與「this」運行在相同的範圍內。如果一個函數稍後被調用,它可能運行在一個完全不同的範圍內,並帶有它自己的「this」概念。

在您的示例中,作爲成功回調提供的匿名函數將在稍後運行,並且它不會與定義回調時運行的代碼的作用域相同「this」。這就是爲什麼你會得到一個錯誤:renderLeaveGoal被定義在回調被定義的範圍內,但不是回調將被執行的範圍。

現在,爲了使這更混亂,變量當回調定義是回調的範圍內可用的定義。這就是爲什麼deltanovember的答案有效。通過在定義成功回調時在變量中僞裝「this」,回調仍然可以在稍後運行時訪問它,儘管範圍完全不同。

我希望這是有道理的。註釋如果沒有,我會再試一次:)

+0

啊,你的兩個答案很好地結合在一起。我試圖弄清楚爲什麼這會在定義變量時起作用,而不是直接調用它。現在我明白了。我只需要保存這個實例,因此保存了將來要調用該函數的範圍。 – egidra 2012-04-21 18:23:58

2

您還可以使用下劃線的bindAll功能,像這樣:

initialize: function() { 
    _.bindAll(this); 
} 

在幕後,下劃線將替換爲對象的所有函數調用代理版本將「this」設置爲與原始對象相同的「this」。當然,如果你的一個方法裏面有它自己的匿名回調函數,那麼你需要完成整個「self = this」舞蹈; bindAll僅修復對象上「外部」方法的上下文。

我已經習慣於使用_.bindAll作爲每個View的initialize()方法的第一行。