2012-04-21 3 views
3

기능을 클릭에 바인딩하는 이벤트가 있습니다. 클릭하면 같은보기에서 다른 기능이 호출됩니다. 불행히도 범위가 올바른 범위가 아닙니다. this.otherFunction()을 수행하려고 시도 할 때 클릭에 할당 된 함수가 this.otherFunction()과 같은 범위에 있지 않습니다. 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()); 
}, 

다음은 모두 동일한보기입니다. 잡히지 않은 TypeError : Object [object DOMWindow]에 'renderLeaveGoal'메서드가 없습니다. 이게 내가 잘못된 범위를 저장 한 것 같니?

+0

코드를 추가 할 수 있습니까? – ataddeini

답변

5

표준 기술은 그럼 당신은 당신이 필요로하므로,이 기능은 뷰에 연결되어

this.otherFunction(); 
+0

흠, 함수를 다시 호출하려고 할 때 내 초기화 함수에서 작동하지만 작동하지 않는 것 같습니다. – egidra

+0

이것은 Dan M의 설명에 비추어 여전히 문제입니까? – deltanovember

+0

예, 여전히 작동하지 않습니다. 나는 결론에 뛰어 올랐다. 내 문제에 대해 편집을했다. – egidra

1

대신에

self.otherFunction(); 

을 할 수

var self = this; 

처럼 뭔가를 할 것입니다 View 객체를 호출하여 호출합니다. 뷰 기능이 자동으로 뷰의 컨텍스트에 바인딩되어 있기 때문에

success: this.renderLeaveGoal 

는이 경우에, 당신은 익명 함수가 필요하지 않습니다.

2

deltanovember의 대답은 정확하지만 그는 그것이 올바른, 그리고 내가 그 중요 느낌 이유를 설명하지 않았다

범위는 자바 스크립트의 혼란이다. 나는 그것을 추적하는 가장 쉬운 방법은 에 대해 생각할 때 무언가가 실행될 것이라고 생각했습니다. 코드 블록이 즉시 실행되면 "this"와 같은 범위에서 실행되고있을 것입니다. 함수를 나중에 호출하려고하면 "this"라는 자체 개념으로 완전히 다른 범위에서 실행됩니다.

예를 들어, 성공 콜백으로 제공하는 익명 함수는 나중에 실행되며 콜백이 정의 될 때 실행중인 코드와 동일한 "this"로 범위가 지정되지 않습니다. 이것이 오류를 일으키는 이유입니다. renderLeaveGoal은 콜백이 정의 된 범위에서 정의되었지만 콜백이 실행되는 범위에서는 정의되지 않았습니다. 이제

이 더 혼란, 변수를 만들려면 콜백이 그 콜백의 범위 내에서 사용할 수를 정의 할 때 정의했다. 이것이 deltanovember의 대답이 작동하는 이유입니다. 성공 콜백이 정의 될 때 변수에서 "this"를 가장함으로써 콜백은 완전히 다른 범위에도 불구하고 나중에 실행될 때 콜백에 계속 액세스 할 수 있습니다.

나는 그것이 의미가 있기를 바랍니다. 그렇지 않은 경우 코멘트, 나는 다시 시도 할 것이다 :

+0

아, 두 답변이 잘 어울립니다. 나는 이것이 이것을 직접 호출하는 것과 반대로 변수가 정의되었을 때 왜 이것이 효과가 있었는지 알아 내려고 노력했다. 자, 알아. 이 인스턴스를 저장해야하기 때문에 앞으로 함수를 호출 할 범위를 절약 할 수 있습니다. – egidra

2

을 또한과 같이 밑줄의 bindAll 기능을 사용할 수 있습니다

장면 뒤에
initialize: function() { 
    _.bindAll(this); 
} 

, 밑줄 모든 기능은 객체에 호출을 대체합니다 "this"가 원본 객체와 동일하게 설정되는 프록시 버전.물론, 여러분의 메소드 중 하나가 그 안에 익명의 콜백 함수를 가지고 있다면, 전체 "self = this"댄스를 할 필요가 있습니다; bindAll은 객체에 대한 "외부"메소드의 컨텍스트 만 수정합니다.

각 View의 initialize() 메소드의 첫 번째 줄에 _.bindAll을 사용하는 습관이 생겼습니다.

관련 문제