2012-07-02 4 views
0

라우터에 addPost 기능이 있습니다. 나는 postAddView에게 함수가 호출 될 때마다 다시 생성하지 않으 :Backbone.js - 다른보기를 렌더링 한 후에 이벤트 트리거가 작동하지 않습니다.

addPost: function() { 
    var that = this; 
    if (!this.postAddView) { 
    this.postAddView = new PostAddView({ 
     model: new Post() 
    }); 
    this.postAddView.on('back', function() { 
     that.navigate('#/post/list', { trigger: true }); 
    }); 
    } 

    this.elms['page-content'].html(this.postAddView.render().el); 
} 

다음은 PostAddView입니다 :

PostAddView = backbone.View.extend({ 
    events: { 
    'click #post-add-back': 'back' 
    } 
    , back: function (e) { 
    e.preventDefault(); 
    this.trigger('back'); 
    } 
}); 

postAddView이 렌더링 처음, 이벤트 트리거가 잘 작동합니다. 그러나 다른보기를 page-content으로 렌더링하고 postAddView을 다시 렌더링하면 이벤트 트리거가 더 이상 트리거되지 않습니다. 그래도 addPost 버전이 제대로 작동합니다.

addPost: function() { 
    var that = this, view; 

    view = new PostAddView({ 
    model: new Post() 
    }); 

    this.elms['page-content'].html(view.render().el); 

    view.on('back', function() { 
    delete view; 
    that.navigate('#/post/list', { trigger: true }); 
    }); 
} 

답변

2

어딘가에 당신은 jQuery의 remove와이 요소 외에 자체에서

것으로, 요소와 관련된 모든 바인딩 이벤트 및 jQuery를 데이터가 제거됩니다 요구하고있다.

그래서 delegate 호출하는 백본은 postAddView.el에 손실됩니다 이벤트를 바인딩하는 데 사용합니다. 그런 다음 postAddView.el을 다시 추가하면 더 이상 연결된 delegate이없고 이벤트가 트리거되지 않습니다. Backbone.View의 표준 remove 메서드는 jQuery의 remove을 호출합니다. empty이 이벤트 처리기와 비슷한 기능을 수행하는 것처럼 jQuery의 몇 가지 다른 기능이 있습니다. 그래서 delegate을 죽이는 실제 함수 호출은 다른 것의 깊숙한 곳에 숨겨 질 수 있습니다.

수동 delegateEvents를 호출 시도 할 수 :

this.elms['page-content'].html(this.postAddView.render().el); 
this.postAddView.delegateEvents(); 

이상, 단지 멀리 볼을 던져 새로운 하나를 당신이 그것을 필요로 할 때마다 만들 수 있습니다. 뷰 객체는 매우 가벼워야하므로 새 뷰를 만드는 것이 기존 뷰를 손으로 추적하려고하는 것보다 저렴하고 번거롭게해야합니다.

1

현재 DOM을 재사용하고보기를하고 싶다면 다시 입력 할 필요가 없습니다. .html()이라고 부르는 모든 것을보기의 DOM을 파괴하고 다시 생성하고 이벤트를 잃게됩니다. . 또한 뷰를 렌더링하기 전에 항상 DOM에 "el"을 추가하는 것을 선호합니다. 나는이 방법으로 당신의 기능을 가지게 될 것입니다 :

addPost: function() { 
    if (!this.postAddView) { 
    this.postAddView = new PostAddView({ 
     model: new Post() 
    }); 
    this.postAddView.on('back', this.onBack); 
    this.elms['page-content'].html(this.postAddView.el); 
    } 

    this.postAddView.render(); 

}, 

onBack : function() { 
    this.navigate('#/post/list', { trigger: true }); 
} 

저는 "this"를 언급하기 위해 지역 변수를 사용하는 것을 좋아하지 않습니다. 모든 뷰가 초기화 메소드에서 _.bindAll(this)을 사용하면 이벤트를 뷰에 바인딩 할 수 있으며이를 사용할 수 있습니다 (onBack을 어떻게 변환했는지 확인하십시오).

내 코드를 사용하면 수동으로 전화 할 필요가 없습니다. this.delegateEvents()

관련 문제