2013-10-11 4 views
2

어떤 방식 으로든 마리오 네트 Layout을 확장하는 것이 가능한지 알고 싶습니다. 탐색과 같은 스택을 만드는 방법을 기반으로합니다.마리오네트 레이아웃 내의 마리오네트 아이템 뷰 스택 유지

마리오네트 동작.

지역 전에 show()보기는 현재 표시된보기에서 close()을 호출합니다. close()view의 소멸자 역할을하여 모든 이벤트의 바인딩을 해제하고 쓸모 없게 만들고 가비지 컬렉터가 처리하도록 허용합니다.

내 시나리오.

는 I 제어부와 제 디스플레이로서 Layout 작용이 ItemView가 호출 네비게이션기구의 일종 있다고 가정하고 클릭 어딘가에 B에 (실시 예 A에 대한 것처럼,이 시점에서 ItemView B.로 동작을 전환 할 수 뒤로 버튼을 탭)을 다시 작성하지 않고 으로 돌아갈 수 있습니다.

다시 작성하지 않고 이전 시나리오를 달성하는 방법은 무엇입니까? 상태를 유지 보수합니까?

iOS 사용자의 경우 UINavigationController과 유사하게 모방하고 싶습니다.

어떤 조언이 필요합니까?

편집

내 목표는 다시 만들지 않고 상태와 이전 캐시 된 뷰를 복원하는 것입니다.

내 시나리오는 다음과 같습니다. 나는 두 개의 영역을 가진 레이아웃을 가지고있다 : A e B A와 A의 어느 곳에서나 클릭하고 B는 C와 D를 닫기 위해 닫힌다. 이제 다시 클릭하면 A와 B가 상태로 복원된다. 이벤트, 모델 등 ...하지만 뷰가 닫혀 있기 때문에 이벤트가 제거됩니다.

답변

4

백본 라우터를 사용하여 URL 변경 이벤트를 수신합니다. 각보기의 경로를 설정 한 다음 라우터가 레이아웃을 호출하여 각 경로에 대한 응답으로 표시되는보기를 변경하게합니다. 사용자는 몇 번이나 뒤로 또는 앞으로 클릭 할 수 있으며 그에 따라 앱이 응답하고 올바른보기를 표시합니다. 직접 호출 할 필요가 없습니다 라우터와 레이아웃 사이의 통신

var Layout = Backbone.Marionette.Layout.extend({ 

    regions: { 
     someRegion: 'my-region-jquery-selector' 
    }, 

    initialize: function() { 
     this.createViews(); 
    }, 

    createViews: function() { 
     this.views = { 
      a: new Backbone.Marionette.ItemView, 
      b: new Backbone.Marionette.ItemView 
     }; 
    }, 

    showItemView: function (view) { 
     this.someRegion.show(this.views[view]); 

     // You might want to do some other stuff here 
     // such as call delegateEvents to keep listening 
     // to models or collections etc. The current view 
     // will be closed but it won't be garbage collected 
     // as it's attached to this layout. 
    } 
}); 

방법 :

var Router = Backbone.router.extend({ 
    routes: { 
     'my/route/itemViewA': 'showItemViewA', 
     'my/route/itemViewB': 'showItemViewB' 
    }, 

    showItemViewA: function() { 
     layout.showItemView('a'); 
    }, 

    showItemViewB: function() { 
     layout.showItemView('b'); 
    } 
}); 

레이아웃은 다음과 같이 보일 수 있습니다처럼 라우터가 보일 수 있습니다. 응용 프로그램 전체의 이벤트를 트리거하거나 생각할 수있는 다른 작업을 수행 할 수 있습니다. 위의 라우터는 매우 기본이지만 작업이 완료됩니다. 매개 변수가있는 단일 경로를 사용하여 표시 할 itemView를 동적으로 결정하기 위해보다 지능적인 라우터를 만들 수 있습니다.

사용자가보기를 변경해야하는 작업을 수행 할 때마다 router.navigate('my/route/itemViewB', {trigger: true});을 사용하여 브라우저의 기록을 업데이트 할 수 있습니다. 또한 히스토리 변경 이벤트 만 렌더링하도록 앱을 설정하면 각보기를 렌더링하는 두 가지 메커니즘을 설정할 필요가 없습니다.

내 자신의 응용 프로그램에서이 패턴을 사용하고 아주 잘 작동합니다.

+0

답변 해 주셔서 감사합니다. 이 경우 가능하다면 라우팅 메카니즘을 피할 수 있습니다. 어떤 충고? –

+0

당신은 뒤로 버튼을 클릭 할 때 발생하는 이벤트가 필요하며 URL 변경 이벤트 수신에 의존한다고 말했을 것입니다. 다른 모든 솔루션은 라우터 기능을 복제합니다. 당신이 그것을 사용하고 싶지 않은 특별한 이유가 있습니까? 참고 : 나는 중요한 정보를 외부에 남겨 두었을 수도 있으므로, 내 대답을 업데이트했습니다. – Simon

+0

지원해 주셔서 감사합니다. 'showItemViewA'를 구현하는 방법을 보여줄 수 있습니까? 나의 목표는 다음과 같다. 뷰를 다시 만들지는 않지만 이전에 저장된 뷰를 복원하십시오. –

3

@ Simon의 답변은 올바른 방향으로 향하고 있습니다. 그러나 Marionette이보기를 닫지 않게하는 유일한 방법은 약간의 Region 코드를 수정하는 것입니다.

var NoCloseRegion = Marionette.Region.extend({ 
    open: function(view) { 
     // Preserve the currentView's events/elements 
     if (this.currentView) { this.currentView.$el.detach(); } 

     // Append the new view's el 
     this.$el.append(view.el); 
    } 
}); 

제 1, 대신 기존의 뷰를 닫습니다 show를 호출,

var Layout = Backbone.Marionette.Layout.extend({ 
    regions: { 
     someRegion: { 
      selector: 'my-region-jquery-selector', 
      regionType: NoCloseRegion 
     }, 
    }, 
    initialize: function() { 
     this.createViews(); 
    }, 
    createViews: function() { 
     this.views = { 
      a: new Backbone.Marionette.ItemView, 
      b: new Backbone.Marionette.ItemView 
     }; 
    }, 
    showItemView: function (name) { 
     // Don't `show`, because that'll call `close` on the view 
     var view = this.views[name]; 
     this.someRegion.open(view) 
     this.someRegion.attachView(view) 
    } 
}); 

이제 레이아웃보기를 만들 때 새로운 렌더링, 새로운 지역 클래스를 지정해야하고,에 첨부 할 때 지역 (그리고 약간 사건을 방아쇠를 당긴다), 우리는 오래된 전망을 분리하고, 새것을 붙이고, 열 수있다.

관련 문제