2014-10-17 6 views
2

을 백본 라우터로 트랩합니다. 상상해보십시오, 나는 2 개의 백본 라우터를 가지고 있습니다 :백본 멀티 라우터 트랩 - 서브 라우터 핸들러가

1) RootRouter - 오직 하나의 라우트와 유일한 책임을 가지고 있습니다 - RequireJS로 인스턴스 subRouters를 인스턴스화하십시오.

var RootRouter = Backbone.Router.extend({ 
    routes: { 
     '*all': 'invokeSubModule' 
    }, 
    invokeSubModule: function(route, args) { 
     require(['SubRouter'], function(subRouter) { 
      new subRouter() 
     }) 
    } 
}); 

2) 경로 해시 및 처리기가있는 SubRouter - 표준 BB 라우터.

var SubRouter = Backbone.Router.extend({ 
    routes: { 
     'some/bar': 'doBar', 
     'some/foo': 'doFoo' 
    }, 
    doBar: function() { ... }, 
    doFoo: function() { ... } 
}); 

URL을 some/bar에서 시작합니다. 시작시 RootRouter 인스 턴싱 및 Backbone.History이 시작됩니다. 예상대로 RootRouter - 모든 URL과 일치하고 invokeSubModule - 비동기로드 및 SubRouter 인스턴스가 예상대로 작동하지만 문제는 some/barSubRouter과 관련이 있습니다. 페이지 URL이 마지막으로 변경되지 않았으므로 처리기가 실행되지 않습니다. route.

해결책을 찾으려면 역사가 시작되기 전에 케이스 u로드 서브 라우터에 대한 해답을 찾았지만 내 경우에는 쓸모가 없습니다.

따라서 파고 들자면 솔루션을 찾았습니다. Backbone.getHash()이 작동하는 루트 메서드와 동일한 경우 Backbone.Route를 확장하고 route 메서드를 오버레이하여 처리기를 호출 할 수 있습니다.

Backbone.Router.extend({ 
    route: function(route, name, callback) { 
     ... 
     if (!callback) callback = this[name]; 

     /* run handler immediately if route we add is the current URL fragment */ 
     if(routeRegexp.test(Backbone.history.getHash())) { 
      this.execute(callback, this._extractParameters(routeRegexp, routeStr)); 
     } 

     Backbone.history.route(route, function(fragment) { 
      .... 
     }); 

     return this; 
    } 
}) 

그래서 난 그냥 혼란스러워하고 미래에 가능한 버그가 발생할 수 있습니다. 그래서 내 솔루션의 이러한 문제와 비평을 해결하는 방법을 모범 사례로 찾고 있습니다.

또한이 경우에는 먼저 route이 (가) 발생하지 않도록 RootRouter없이 라우터 지연로드를 관리하는 방법에 대한 가능한 답변을 기대합니다.

+0

가이처럼'RootRouter''route' 이벤트에 가입하려고 했 전체 샘플 아래

:'RootRouter.on를 ("경로

UPDATE 최대 : invokeSubModule ", function (url) {SubRouter.navigate (url); })'? – Dethariel

+0

'navigate'는 콜백을 파편으로 여전히 트리거하지 않을 것이기 때문에 작동하지 않을 것입니다. 현재의 솔루션은 작동하지만, 백본 아이디어를 깨트 렸는지 모르겠다. 자전거가 다시 발명되지 않았다. – Evgeniy

답변

2

백본 라우팅의 내부를 해킹하지 않고도 필요한 동작을 복제 할 수 있었지만 초기화 과정에서 일부 작업을 수행해야했습니다.

처음 난

var mainRouter = new RootRouter(); 
Backbone.history.start({silent: true}); 

이 시작됩니다 백본 역사, 그러나 현재의 URL을 라우팅하지 않고 진정한 = 주요 라우터를 만들고 침묵 옵션에 백본 역사를 시작합니다. 는 내가이 방식의 나쁜 측면은 당신이 처음에 2 라우팅을 할 필요가있다 원래 조각

var fragment = Backbone.history.fragment; 
mainRouter.navigate('reset',true); 
mainRouter.navigate(fragment, true); 

에 다음, 현재의 단편을 가지고 나중에 사용할 수 있도록 저장 한 다음 기본 URL에 탐색

<html><head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
    <title> sample </title> 

    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script> 
    <script type="text/javascript" src="http://underscorejs.org/underscore-min.js"></script> 
    <script type="text/javascript" src="http://backbonejs.org/backbone-min.js"></script> 


    <style type="text/css"> 

    </style> 

    <script> 
    var RootRouter = Backbone.Router.extend({ 
    routes: { 
     '*all': 'invokeSubModule', 
     'reset': 'invokeSubModule', 
    }, 
    invokeSubModule: function(route, args) { 
     new SubRouter(); 
    }, 

    navigate: function() { 
       Backbone.Router.prototype.navigate.apply(this, arguments); 
      }, 

    execute: function(callback, args) { 
       console.log('execute root'); 
       Backbone.Router.prototype.execute.apply(this, arguments); 
       console.log ('current fragment ' + Backbone.history.fragment); 
      } 
    }); 

    var SubRouter = Backbone.Router.extend({ 
    routes: { 
     'some/bar': 'doBar', 
     'some/foo': 'doFoo' 
    }, 

    navigate: function() { 
       Backbone.Router.prototype.navigate.apply(this, arguments); 
      }, 
    execute: function(callback, args) { 
       console.log('execute sub'); 
       Backbone.Router.prototype.execute.apply(this, arguments); 
       console.log ('current fragment ' + Backbone.history.fragment); 
      }, 
    doBar: function() { 
     $('#content').html('').append('<p>BAR</p>'); 
    }, 
    doFoo: function() { 
     $('#content').html('').append('<p>FOO</p>'); 
    } 
}); 

    $(document).ready(function(){ 
     var mainRouter = new RootRouter(); 
     Backbone.history.start({silent: true}); 
     var fragment = Backbone.history.fragment; 
     mainRouter.navigate('#',true); 
     mainRouter.navigate(fragment, true); 

     $('a').click(function(){ 
      mainRouter.navigate($(this).attr('href')); 
     }); 
    }); 
    </script> 

</head> 
<body> 
    <a id='home' href="#">home</a></br> 
    <a id='foo' href="#/some/foo">foo</a></br> 
    <a id='bar' href="#/some/bar">bar</a></br> 
    <div id='content'>HOME</div> 
</body></html> 
+0

그러나이 접근법은 모든 모듈로드에서 내력을 재설정하도록 강제 할 것인가? – Evgeniy

+0

아니요 각 모듈로드시 재설정 할 필요가 없습니다. 문서 준비 이벤트의 경로 재설정으로 이동하므로 하위 뷰를로드하기 전에 하위 라우터가로드되어 있는지 확인하고 조각 변수를 확인할 수 있습니다. 로드 된 올바른 하위 라우터를 얻으십시오 – mfarouk

+0

테스트 할 수 있도록 전체 코드로 답변을 업데이트합니다 – mfarouk