2012-07-31 3 views
1

깨끗한 코드베이스를 유지하기 위해 https://github.com/addyosmani/backbone-aura/의 모듈러 및 facade/mediator pub/sub 패턴을 모듈간에 전송하는 애플리케이션을 백본에 구축하고 있습니다.메디 에이터 펍/서브 패턴을 사용할 때 백본 앱 라우팅

분위기를위한 전체 앱 예제에서 Grepping을 사용하면 모듈 자체의 일부인 라우터의 이상적인 사용을 설명하는 readme 파일 만 발견했습니다. "Backbone.js 용어로 위젯은 모델, 뷰, 컬렉션 및 위젯을 렌더링하는 데 필요한 모든 템플릿뿐만 아니라 라우터도 사용할 수 있습니다. "

그래서 라우트를 설정하기 위해 set-route 메시지를 허용하는 라우터 모듈과 route 메시지를 수신하는 모듈을 포함하여 확장 가능한 라우팅 시스템 (확장 가능한 모듈은 자체 서브 루틴을 지정할 수 있음)을 구현하기위한 여러 가지 솔루션을 시도했습니다. 모듈 당 하위 라우터도 사용했습니다. 문제는 초기 페이지로드시 메시징의 '비동기'특성으로 인해 글로벌 라우터가 URL을 구문 분석 할 때 경로와 해당 콜백을 정의하지 못할 수 있습니다. 라우터 모듈을 시작하기 전에 모든 메시지를 대기시켜야 할 수도 있습니다.

나는 깨끗한 것을 구현하고 싶다. 또한 잠재적으로 모든 위젯의 모든 경로를 먼저 파싱 한 다음 라우터를 인스턴스화하여 라우터 모듈을 특별한 경우로 만들려고하고 따라서 모듈의 일부가 아니어야한다고 생각했습니다.

라우터가 메시지를 사용하는 모듈이거나 확장 모듈이거나 모듈이 액세스 할 수있는 글로벌 상위 아키텍처이어야합니까?

로드 된 질문이므로 미리 도움을 청하십시오!

답변

1

이 문제에 대해 많은 논란이있었습니다. 라우터를 공식적으로 컨트롤러라고 부르는 것이 혼란이라고 생각합니다. 작년 말 백본을 사용하기 시작했을 때 이미 변경이 있었지만 많은 사람들이 이미 라우터를 중심으로 컨트롤러를 구축하고 있다고 생각합니다. 나는 결코 그것에 동의하지 않았다. Backbone이 만들어지기 오래 전부터 Backbone과 비슷한 독점적 인 MVC 엔진을 구축 한 경험에 의존하여 - 라우터는 단순히 내역 관리자 구성 요소였습니다.

그래서 가장 좋은 몇 가지를, 라우터를 구현 고려하는 방법 결정에 특정 문제를 해결하기 위해 : 모든

  1. 첫째, 라우터는 응용 프로그램의 필수 구성 요소가 아닙니다. 라우터 없이도 앱의 다양한 페이지 나 화면으로 이동할 수 있습니다.
  2. 라우터는 주 기능이 기록을 관리한다는 점에서 컨트롤러가 아닙니다. 애플리케이션 비즈니스 로직을 라우터에 내장 할 수는 있지만, 라우터가 실제로하는 일의 물을 왜곡하는 것으로 항상 깨달았습니다.
  3. 라우터를 응용 프로그램의 구성 요소로 만들면 우려 사항을 효과적으로 분리 할 수 ​​있으며 훨씬 더 효과적인 pub/sub 유형의 배열을 가질 수 있습니다.다음은

는 중재자, 술집/하위 패턴 다음 내 응용 프로그램에서 사용하는 라우터 모듈에 대한 코드입니다 : 내가 구성 요소를 인스턴스화 할 때, 나는 그것을 있도록지도를 통과 그런

/** 
* The idea behind this component is simply to relegate Backbone.Router to 
* doing what it does best: History Management. All it is responsible for 
* is two things: 
* 
* 1. Update the URL if router.navigate is invoked 
* 2. Trigger a routeChanged event if the URL was updated either by a bookmark or 
* typed in by a user. 
*/ 
define(function() { 
    return Backbone.Router.extend({ 
     initialize : function (map) { 
      this._reversedMap = this.reverseModuleMap(map); 
     }, 
     routes:{ 
      '*actions':'notify' 
     }, 
     notify:function (actions) { 
      var args = arguments; 
      this.trigger("routeChanged", {command:actions}); 
     }, 
     /** 
     * Override Backbone.Router.navigate. Default is to pass a router fragment, but for 
     * our uses, we'll translate the "route" into a module mapping so that the controller 
     * will know which module to display. 
     * @param param 
     * @param options 
     */ 
     navigate:function (param, options) { 
      //console.log('navigate', param); 
      if(!param.suppressNavigate && param.actionCommand) { 
       Backbone.Router.prototype.navigate.call(this, this._reversedMap[param.actionCommand]); 
      } else if(!param.actionCommand) { 
       Backbone.Router.prototype.navigate.call(this, param, options); 
      } 
     }, 
     /** 
     * this function simply reverses the key and value of the "map" 
      * @param map 
     */ 
     reverseModuleMap:function (map) { 
      var newMap = {}; 
      _.each(map, function (value, key) { 
       newMap[value] = key; 
      }); 
      // reversed key and value 
      return newMap; 
     } 
    }); 
}); 

을 내 컨트롤러는 모듈로 이동합니다 알고 :

this._router = new Router({ 
    _default: 'moduleA', 
    sites : 'moduleA', 
    apps : 'moduleB' 
}); 
this._router.on('routeChanged', this.handleRouteChange, this); 

나는이 발견 한 가장 중요한 것은이 코드 좋은 및 간단한 유지한다는 것입니다, 그리고 내 컨트롤러에서 비즈니스 로직에 집중할 수 있습니다.

관련 문제