[backbone.js] Backbone.js : 현재 경로 가져 오기

Backbone을 사용하면 현재 경로의 이름을 얻을 수 있습니까? 경로 변경 이벤트에 바인딩하는 방법을 알고 있지만 변경 사이에 다른 시간에 현재 경로를 결정할 수 있기를 원합니다.



답변

응용 프로그램에서 라우터를 인스턴스화 한 경우 다음 줄은 현재 조각을 반환합니다.

Backbone.history.getFragment();

로부터 Backbone.js 문서 :

“[…] 역사 핸들 hashchange 이벤트 또는 pushState에 (프레임 당) 글로벌 라우터의 역할을, 콜백을 적절한 경로를 일치 및 트리거 혹시이 자신을 하나 만들 필요가 없습니다 -. 당신이 참조를 사용한다을 경로가있는 라우터를 사용 하면 자동으로 생성되는 Backbone.history에 연결됩니다 . […] “

해당 조각에 바인딩 된 함수 이름이 필요한 경우 라우터 범위 내에서 다음과 같이 만들 수 있습니다.

alert( this.routes[Backbone.history.getFragment()] );

또는 라우터 외부에서 다음과 같이하십시오.

alert( myRouter.routes[Backbone.history.getFragment()] );


답변

Robert의 대답 은 흥미롭지 만 안타깝게도 해시가 경로에 정의 된 대로만 작동합니다. 예를 들어 경로 가있는 경우 또는 경로 중 하나 인 user(/:uid)경우 일치하지 않습니다 (둘 다 해당 경로의 가장 명백한 두 가지 유스 케이스입니다). 다시 말해서, 해시가 정확히 (매우 가능성이 낮 다면) 적절한 콜백 이름 만 찾습니다 .Backbone.history.fragment"user""user/1""user(/:uid)"

이 기능이 필요했기 때문에 History 및 Router 객체가 적절한 콜백을 트리거하기 위해 정의 된 경로와 현재 조각을 일치시키기 위해 사용하는 일부 코드를 재사용 Backbone.Router하는 current– 기능으로 확장했습니다 . 내 유스 케이스의 경우 선택적 매개 변수를 사용합니다.이 매개 변수 route를 true로 설정하면 경로에 대해 정의 된 해당 함수 이름이 반환됩니다. 그렇지 않으면에서 현재 해시 조각을 반환합니다 Backbone.History.fragment.

Backbone 라우터를 초기화하고 설정하는 기존 Extend에 코드를 추가 할 수 있습니다.

var Router = new Backbone.Router.extend({

    // Pretty basic stuff
    routes : {
        "home" : "home",
        "user(:/uid)" : "user",
        "test" : "completelyDifferent"
    },

    home : function() {
        // Home route
    },

    user : function(uid) {
        // User route
    },

    // Gets the current route callback function name
    // or current hash fragment
    current : function(route){
        if(route && Backbone.History.started) {
            var Router = this,
                // Get current fragment from Backbone.History
                fragment = Backbone.history.fragment,
                // Get current object of routes and convert to array-pairs
                routes = _.pairs(Router.routes);

            // Loop through array pairs and return
            // array on first truthful match.
            var matched = _.find(routes, function(handler) {
                var route = handler[0];

                // Convert the route to RegExp using the 
                // Backbone Router's internal convert
                // function (if it already isn't a RegExp)
                route = _.isRegExp(route) ? route :  Router._routeToRegExp(route);

                // Test the regexp against the current fragment
                return route.test(fragment);
            });

            // Returns callback name or false if 
            // no matches are found
            return matched ? matched[1] : false;
        } else {
            // Just return current hash fragment in History
            return Backbone.history.fragment
        }
    }
});

// Example uses:
// Location: /home
// console.log(Router.current()) // Outputs 'home'
// Location: /user/1
// console.log(Router.current(true)) // Outputs 'user'
// Location: /user/2
// console.log(Router.current()) // Outputs 'user/2'
// Location: /test
// console.log(Router.current(true)) // Outputs 'completelyDifferent'

약간의 개선이 이루어질 수있을 것이지만 이것이 시작을위한 좋은 방법입니다. 또한 Route-object를 확장하지 않고도이 기능을 쉽게 만들 수 있습니다. 이 설정이 가장 편리한 방법이기 때문에이 작업을 수행했습니다.

나는 이것을 아직 완전히 테스트하지 않았으므로 남쪽으로 가면 알려주십시오.


2013 년 4 월 25 일 업데이트

함수에 약간의 변경을가 했으므로 해시 또는 경로 콜백 이름을 반환하는 대신 조각, 매개 변수 및 경로가있는 객체를 반환하므로 경로에서와 마찬가지로 현재 경로의 모든 데이터에 액세스 할 수 있습니다. 행사.

아래 변경 사항을 볼 수 있습니다.

current : function() {
    var Router = this,
        fragment = Backbone.history.fragment,
        routes = _.pairs(Router.routes),
        route = null, params = null, matched;

    matched = _.find(routes, function(handler) {
        route = _.isRegExp(handler[0]) ? handler[0] : Router._routeToRegExp(handler[0]);
        return route.test(fragment);
    });

    if(matched) {
        // NEW: Extracts the params using the internal
        // function _extractParameters 
        params = Router._extractParameters(route, fragment);
        route = matched[1];
    }

    return {
        route : route,
        fragment : fragment,
        params : params
    };
}

추가 주석 및 설명은 이전 코드를 참조하십시오.


답변

호출 된 경로 처리기에서 호출 경로 (또는 URL)를 얻으려면 확인하여 얻을 수 있습니다.

Backbone.history.location.href ... 전체 URL
Backbone.history.location.search ...?에서 시작하는 쿼리 문자열?

나는이 답변을 찾기 위해 여기에 왔으므로 내가 찾은 것을 떠나야한다고 생각합니다.


답변

라우터의 루트 설정을 사용하는 경우 ‘실제’조각을 얻기 위해 포함시킬 수도 있습니다.

(Backbone.history.options.root || "") + "/" + Backbone.history.fragment


답변

Simon의 대답에 대한 더 장황한 (또는 취향에 따라 더 읽기 쉬운) 버전이 있습니다 .

current: function () {
  var fragment = Backbone.history.fragment,
      routes = _.pairs(this.routes),
      route,
      name,
      found;

  found = _.find(routes, function (namedRoute) {
    route = namedRoute[0];
    name = namedRoute[1];

    if (!_.isRegExp(route)) {
      route = this._routeToRegExp(route);
    }

    return route.test(fragment);
  }, this);

  if (found) {
    return {
      name: name,
      params: this._extractParameters(route, fragment),
      fragment: fragment
    };
  }
}


답변

의 소스를 보면 Router라우터가 무언가 변경되었다는 이벤트를 트리거하면 이름이 “route : name”으로 전달됨을 알 수 있습니다.

http://documentcloud.github.com/backbone/docs/backbone.html#section-84

라우터에서 항상 “경로”이벤트를 연결하고 저장하여 현재 경로를 얻을 수 있습니다.


답변