2013-07-23 3 views
3

사이드 바 및 여러 하위보기로 구성된 단일 백본보기가 있습니다. 단순화를 위해 사이드 바 및 하위보기가 단일 render 함수에 의해 관리되도록하기로 결정했습니다. 그러나 사이드 바 항목 중 하나를 클릭하면 click .edit 이벤트가 여러 번 실행되는 것으로 보입니다. 예를 들어 '일반'으로 시작하여 .edit을 클릭하면 hello 번만 실행됩니다. 사이드 바에서 .profile을 클릭하고 .edit을 다시 클릭하면 hello이 두 번 발생합니다. 어떤 아이디어?하위보기를 다시 랜더링 한 후에 백본 이벤트가 여러 번 발생합니다.

보기

events: { 
    "click .general": "general", 
    "click .profile": "profile", 
    "click .edit": "hello", 
}, 

general: function() { 
    app.router.navigate("/account/general", {trigger: true}); 
}, 

profile: function() { 
    app.router.navigate("/account/profile", {trigger: true}); 
}, 

render: function(section) { 
    $(this.el).html(getHTML("#account-template", {})); 
    this.$("#sidebar").html(getHTML("#account-sidebar-template", {})); 
    this.$("#sidebar div").removeClass("active"); 
    switch (this.options.section) { 
    case "profile": 
     this.$("#sidebar .profile").addClass("active"); 
     this.$("#content").html(getHTML("#account-profile-template")); 
     break; 
    default: 
     this.$("#sidebar .general").addClass("active"); 
     this.$("#content").html(getHTML("#account-general-template")); 
    } 
}, 

hello: function() { 
    console.log("Hello world."); 
}, 

라우터

account: function(section) { 
    if (section) { 
    var section = section.toLowerCase(); 
    } 
    app.view = new AccountView({model: app.user, section: section}); 
}, 

솔루션 내 솔루션은 다음과 라우터 변경했다

:

account: function(section) { 
    if (section) { 
    var section = section.toLowerCase(); 
    } 
    if (app.view) { 
    app.view.undelegateEvents(); 
    } 
    app.view = new AccountView({model: app.user, section: section}); 
}, 

이것은 현재 작동하지만 메모리 누수가 발생합니까?

+1

라우터 코드를 게시하면 중복보기 인스턴스를 생성하고 있음을 확인할 수 있습니다. –

+0

좋아, 라우터의 관련 섹션을 게시했습니다. –

답변

6

백본을 처음 사용하기 시작할 때 정확히 동일한 문제가있었습니다. 피터 (Peter)가 말했듯이, 문제는 뷰의 인스턴스가 두 개 이상 생성되어 이벤트를 수신한다는 것입니다. 당신이 볼 수 있듯이

/* Router view functions */ 
showContact:function() { 
    require([ 
     'views/contact' 
    ], $.proxy(function (ContactView) { 
     this.setCurrentView(ContactView).render(); 
    }, this)); 
}, 
showBlog:function() { 
    require([ 
     'views/blog' 
    ], $.proxy(function (BlogView) { 
     this.setCurrentView(BlogView).render(); 
    }, this)); 
}, 


/* Utility functions */ 
setCurrentView:function (view) { 
    if (view != this._currentView) { 
     if (this._currentView != null && this._currentView.remove != null) { 
      this._currentView.remove(); 
     } 
     this._currentView = new view(); 
    } 
    return this._currentView; 
} 

, 항상 마지막보기를 제거하고 렌더링하는 새로운 하나를 만드는 것 :이 문제를 해결하기 위해, 나는 내 마지막 백본 프로젝트에이 솔루션을 만들었습니다. 나는 라우터에 require 문을 추가한다. 실제로 필요한 때까지 라우터의 모든 뷰를로드하고 싶지 않기 때문이다. 행운을 빕니다.

+0

감사! 나는이 문제를 다루는 유일한 사람이 아니라는 것을 보니 기쁘다. 이것은 훌륭한 해결책입니다. –

+0

@ j-a-x 라우터 및 App 파일을 정렬하는 방법에 대해 자세히 설명 할 수 있습니까? – jeevs

+0

@jeevs 죄송합니다, 잠시 동안 백본을 만지지 않았습니다. 지금 Angular에 있습니다 :) –

0

여러 개의보기 인스턴스를 동일한 DOM 요소에 연결하는 것처럼 들리지만 모두 이벤트에 응답합니다. 이전보기를 제거하지 않고 탐색 할 때마다 새로운보기를 만들고 있습니까?

+0

새로운 뷰를 만들기 전에'app.view.remove()'를 시도했지만 새로운 뷰가 렌더링되지 않습니다. –

+1

글쎄, 렌더링하고 첨부해야합니다. 당신의'undelegateEvents'는 내가 좋아할 것입니다,하지만 당신의 유스 케이스에서 작동 할 수있는 가장 간단한 백본 패턴이라고 생각하지 않습니다. –

+0

나는 제안에 확실히 열려있다 ;-) –

0

나는 라우터 매개 변수에 따라 동일한 요소 (약 12) 안에 다른 템플릿을 렌더링하는 동적보기를 가지고 있습니다. view가 렌더링되는 컨테이너는 view.render() 안에 "el : '# some-container'"처럼 정의됩니다. 당연히,보기가 존재한다면, 새로운 것과 동일한 것을 만들기 전에보기를 제거해야만 좀비와 s #! t를 막을 수 있습니다. 다시 말해서 view.remove()를 호출하면 실제로 DOM에서 'some-container'가 제거됩니다. 즉, 처음에는보기를 제외하고는 렌더링 할 위치가 없습니다. 이제는 이러한 일이 발생하지 않도록하는 수십 가지 방법이 있습니다. 누군가가 몇 시간의 연구를 구해야 할 경우를 대비하여 공유해야한다고 생각했습니다.

관련 문제