1

다시 렌더링 한 후 제출을 클릭하는 동안 문제가 발생했습니다.backbone.js에서 다시 렌더링 한 후 이벤트가 실행되지 않음

ShareHolderInfoView = Backbone.View.extend({ 
template : 'shareholderinfo', 
initialize: function() { 
    this.model = new ShareHolderInfoModel(); 
}, 
render : function() { 
    $.get("shareholderinfo.html", function(template) { 
     var html = $(template); 
     that.$el.html(html); 
    }); 

    //context.loadViews.call(this); 
    return this; 
}, 
events:{ 
    "change input":"inputChanged", 
    "change select":"selectionChanged", 
    "click input[type=submit]":"showModel" 
}, 
inputChanged:function(event){ 
    var field = $(event.currentTarget); 
    var data ={}; 
    data[field.attr('id')] = field.val(); 
    this.model.set(data); 
}, 
showModel:function(){ 
    console.log(this.model.attributes); 
    alert(JSON.stringify(this.model.toJSON())); 
} 
}); 

이 내 라우터

var shareholderInfo, accountOwnerInfo; 

App.Router = Backbone.Router.extend({ 

    routes:{ 
     'share':'share', 
     'joint':'joint' 
    }, 
    share:function(){ 

     $("#subSection").empty(); 
     if(!shareholderInfo){ 
      shareholderInfo = new ShareHolderInfoView(); 
      $("#subSection").append(shareholderInfo.render().el); 
     } else{ 
      $("#subSection").append(shareholderInfo.$el); 
     } 
    }, 
    joint:function(random){ 
     $("#subSection").empty(); 
     if(!accountOwnerInfo){ 
      accountOwnerInfo = new AccountOwnerInfoView(); 
      $("#subSection").append(accountOwnerInfo.render().el); 
     } else{ 
      $("#subSection").append(accountOwnerInfo.$el); 
     } 
    } 
}); 

이 내 HTML 아이디 = '하위'와 사업부입니다 :

이 내이다.

콘솔을 체크인하면 해당보기에 바인딩 된 이벤트를 볼 수 있습니다.

Object {change input: "inputChanged", change select: "selectionChanged", click input[type=submit]: "showModel"} 

하지만 showModel 함수를 호출하지 않으면 전송을 클릭합니다. 도와주세요.

+0

은보기의 엘 안에 제출 버튼입니까? –

답변

5

근본적인 문제는보기를 잘못 재사용한다는 것입니다. fine manual에서

:

.empty()

설명 : 는 DOM에서 일치하는 요소 집합의 모든 자식 노드를 제거합니다.
[...]
jQuery는 메모리 누수를 피하기 위해 요소 자체를 제거하기 전에 자식 요소에서 데이터 및 이벤트 핸들러와 같은 다른 구조를 제거합니다.

그래서 당신은 말할 때 : 당신은 그냥 #subSection의 내용을 삭제하지 않을

$("#subSection").empty(); 

, 당신은 또한 #subSection 내부에 아무것도에 연결된 모든 이벤트 핸들러를 제거하고 있습니다. 특히 accountOwnerInfo.el 또는 shareholderInfo.el (이미 #subSection에있는 이벤트 핸들러에 따라 다름)에 바인딩 된 모든 이벤트 핸들러를 제거합니다.

보기를 재사용하는 것이 일반적으로 가치가있는 것보다 더 어려우므로,보기가 충분히 가벼워 야하며 필요에 따라보기를 재사용 할 수 있습니다. 보기를 파괴하는 올바른 방법은 remove입니다. 이 같은 더보고 라우터를 다시 작성할 수 :

App.Router = Backbone.Router.extend({ 
    routes: { 
     'share':'share', 
     'joint':'joint' 
    }, 
    share: function() { 
     this._setView(ShareHolderInfoView); 
    }, 
    joint: function(random){ 
     this._setView(AccountOwnerInfoView); 
    }, 
    _setView: function(view) { 
     if(this.currentView) 
      this.currentView.remove(); 
     this.currentView = new view(); 
     $('#subSection').append(this.currentView.render().el); 
    } 
}); 

를 귀하의 의견은 다음 기본 remove 전화를 Backbone.View.prototype.remove.call(this)에 엑스트라 다음 체인을 정리하는 그들에 remove을 재정의 할 수 있습니다 여분의 정리가 필요합니다.

당신이 주변에 귀하의 의견을 유지해야하는 몇 가지 이유를 들어, 당신이 그들에 delegateEvents 부를 수있는 경우 :delegateEvents([events])

delegateEvents는 내 DOM 이벤트에 대한 선언 콜백을 제공하기 위해 jQuery의 on 기능을 사용하여 전망.이벤트 해시가 직접 전달되지 않으면 this.events을 원본으로 사용합니다.

당신이 말하고 싶지만 것들과 같은 :

$("#subSection").append(shareholderInfo.$el); 
shareholderInfo.delegateEvents(); 

대신 단지 :

$("#subSection").append(shareholderInfo.$el); 

난 강력하게 당신이 당신의 전망과 저렴한 임시 객체를 치료하는 것이 좋습니다 것 :에 그들을 파괴 페이지에서 삭제할 때 새 페이지를 만들 수 있습니다.

+0

좋은 답변입니다. 나는 내가 여기 왔을 때 그것이 단지 하나의 upvote를 가지고 놀랐다. –

+0

@RyanOre : 감사합니다. 나는이 답변의 여러 버전을 썼다는 것을 확신하지만 중복을 찾지 못할 수도 있습니다. 아무도 찾을 수 없을 것입니다. :) –