2013-02-20 2 views
3

내 응용 프로그램에 주 영역이 있고 기본 영역에 URL로 액세스 할 수있는 하위 영역이있을 때가 있습니다. 주요 지역 콘텐츠는 앱 라우터가 주요 지역을 알고있는 기능에 의해 변경됩니다. 서브 뷰의 임시 영역은 무엇입니까?Backbone.Marionette 경로 변경시 지역 변경

예를 들어, URL /docs에는 문서에 대한 링크 목록이 표시되고 /doc/:id에는 목록 옆에있는 문서의 내용이 표시되어야합니다. 그렇다면 일부 사용자가 새 탭에서 URL을 열 때 일부 사용자가 목록을 클릭하고 목록과 콘텐츠를 모두 렌더링 할 때 /doc/:id이 콘텐츠를 렌더링 할 수 있습니다.

모든 범위의 라우터가있는 두 가지 옵션이 있거나 지역 관리자가 경로와 지역이 변경되어야하는 이벤트를 발생시키는 것을 볼 수 있습니다. 이 문제를 해결할 수있는 가장 좋은 방법에 대한 힌트.

답변

4

나는 모든 지역 솔루션마다 하나의 라우터를 생각해 냈습니다. 라우터는 라우트와 뷰의 맵으로 쉽게 구성 할 수 있습니다. 절대 경로가 일치하면 초기에 통과 한 영역에보기의 새 인스턴스가 표시됩니다.

Here은 경로 매개 변수가보기로 전달되는 라우터의 고급 버전입니다.

이상에서만이 솔루션은 한 모든 경로를 한 번만 등록되어 작동

업데이트. 동일한 경로를 두 번째로 등록하면 첫 번째 콜백이 무시됩니다. 그래서 지역 컨트롤러가 라우트에 라우터를 직접 등록하지 않고 글로벌 이벤트 버스 (Marionette.Application.vent)에서 route:change 이벤트를 수신하고 라우터가이 이벤트 버스에서 route:change 이벤트를 트리거하는 솔루션을 생각해 냈습니다.

RouterController :

// The problem with backbone router is that it can only register one function per route 
// to overcome this problem every module can register routes on the RouterController 
// the router will just trigger an event on the `app.vent` event bus when ever a registered routes match 
define(function() { 

    function RouterController(vent) { 
    this.vent = vent; 
    this.router = new Backbone.Router(); 
    } 

    RouterController.prototype = _.extend({ 
     //just pass the route that change you wanna listen to 
     addRoutes: function(routes) { 
     _.each(routes, function(route) { 
      this.router.route(
      route, 
      _.uniqueId('e'), 
      //create a closure of vent.trigger, so when ever the route match it simply trigger an event passing the route 
//   _.partial(_.bind(this.vent.trigger, this.vent), 'route:change', route) 
      _.bind(function() { 
       this.vent.trigger.apply(this.vent, ['route:change', route].concat(_.toArray(arguments))); 
      }, this) 
     ); 
     }, this); 

     } 
    }, 
    Backbone.Events); 

    return RouterController; 
}); 

RegionRouter :

define(['common/App'], function(app) { 

    function RegionRouter(region, routerSettings) { 
     app.router.addRoutes(_.keys(routerSettings)); 

     this.listenTo(app.vent, 'route:change', function() { 
     var route = arguments[0]; 
     var View = routerSettings[route]; 

     if (!View) { 
      return; 
     } 

     var params; 

     if (arguments.length > 1) { 
      params = computeParams(arguments, route); 
     } 
     region.show(new View(params)); 
     }); 
    } 

    RegionRouter.prototype = _.extend(
     { 
     onClose: function() { 
      this.stopListening(app.vent); 
     } 
     }, Backbone.Events 
    ); 

    function computeParams(args, route) { 
     args = Array.prototype.slice.call(args, 1); 

     //map the route params to the name in route so /someroute/:somevalue will become {somevalue: passedArgs} 
     //this object will be passed under the parameter key of the options 
     var params = {}; 
     var regEx = /(?::)(\w+)/g; 
     var match = regEx.exec(route); 
     var count = 0; 
     while (match) { 
     params[match[1]] = args[count++]; 
     match = regEx.exec(route); 
     } 

     return {params: params}; 
    } 

    return RegionRouter; 
    } 
); 
관련 문제