2013-03-01 2 views
13

의 내가 백본 pushstate을 사용하고 있다고 가정 해 봅시다 내가 검색어 매개 변수가있는 페이지로 이동합니다새 URL을 Backbone.history로 푸시하면 쿼리 매개 변수가 그대로 유지됩니까?

domain.com/user/111?hello=123 

나는이 실행할 때 :

Backbone.history.navigate('/settings', true); 

내 설정 페이지가 완벽하게로드하지만, 안녕하세요 =를? 123 명 URL에 체류 ...

domain.com/settings?hello=123 

그리고 URL에서 해당 쿼리 PARAM의 숙박은 사방이 사이트를 탐색 ...

+0

편집과 같이 될 것이다 : 나는 https://github.com/jhudson8/backbone-query-parameters 플러그인을 사용하고 있습니다. – TIMEX

+0

질문을 좀 더 명확하게 만들 수 있습니까? 다른 페이지로 이동할 때마다'location.search'를 비우고 싶습니까? –

+0

도 [github에]에 약 2 일 전에 게시 된 문제 (https://github.com/jhudson8/backbone-query-parameters/issues/29)에 보인다 및 저자는이 기능에 근무하지 않는 것 같습니다. – Starx

답변

19

백본 라우팅 및 쿼리 매개 변수는 불행한 결혼입니다. 문제는 this GitHub issue에 잘 설명되어 있습니다.

Backbone.Router은 URL 해시 조각 및 pushState API와 함께 작동하도록 설계되어 있습니다. 해시 URL을 사용할 때 쿼리 문자열은 해시 앞에 나오며 경로에서 일치하지 않습니다. pushState를 사용하면 쿼리 문자열은 URL 단편의 일부이므로 다른 경로 표현식이 필요합니다.

은의 당신이 경로 search이있을 것이다라고하자, 그 경로는 선택적 매개 변수 q, sorttype를 취할 것입니다. 같은 보일 것이다 쿼리 문자열과 같이 문제가

search?q=kittens&sort=asc&type=images 

를, 그 이전 버전의 브라우저 사용자를위한, 백본 hashchange 기반 라우팅으로 돌아갑니다, 그리고 경로가 될 것입니다 :

?q=kittens&sort=asc&type=images#search 

플러그인을 사용하면이 문제를 해결하려고 시도하지만 핵심 문제는 해결되지 않습니다.

가능한 경우 쿼리 문자열을 사용하지 말고 경로 표현식에 선택적 조각을 사용하여 상태 정보를 전달해야합니다. 위의 예 경로는 될 것입니다 :

//pushState 
search/q/kittens/sort/asc/type/images 

//hash fragment 
#search/q/kittens/sort/asc/type/images 

(optional) 경로 부품 :captures (docs)를 사용하여 다음과 같은 식으로 URL을 나타낼 수 :만큼 경로 조각에로

var Router = Backbone.Router.extend({ 
    routes: { 
    "search(/q/:query)(/sort/:sort)(/type/:type)": "search" 
    }, 

    search: function(query, sort, type) { 
    console.log(query, sort, type); //-> "kittens", "asc", "images" 
    } 
}); 

을 예를 들어, 지정된 순서와 일치하지 않는 URL, 임의의 모든 매개 변수와 일치합니다.

search      //-> undefined, undefined, undefined 
search/q/kittens/type/images //-> "kittens", undefined, "images" 
search/sort/asc/type/images //-> undefined, "asc",  "images" 

이 w ay 타사 쿼리 문자열 라이브러리 또는 브라우저 호환성에 대해 걱정할 필요가 없습니다. 그리고 나에게 묻는다면 후자의 URL이 더 깨끗해진다.

+1

너무 많은 매개 변수를 슬래시 방식으로 두는 것이 RESTful URL의 원칙에 위배됩니다. 플러스 @ TIMEX의 문제는 플러그인으로 인해 발생합니다. 백본이 슬래시 패션을 추진하고 있지만 스타일 매개 변수가 검색과 같은 특정 기능에 적합하다고 생각합니다. – yujingz

+0

좋은 해결책. 이것은 단지 클라이언트 측이므로 RESTful URL에 대한 아이디어는 어쨌든 여기에 적용되지 않습니다. 작동하는 URL은 모두 정상입니다. – jasop

+0

@ jasop 나는 동의하지 않는다. RESTful URL은 구현 세부 사항 만있는 것이 아닙니다. 그들은 또한 사용자를 바라보고 있으며, 웹 전체에 일관성을 유지하기 위해 RESTful 표준을 준수하는 것이 이상적입니다. 물론 이것은 RESTful 협약의 다소 중대한 위반입니다. 나는 관행을 깨뜨리는 것에 대한 정당한 이유가 없다고 말하는 것이 아닙니다. 클라이언트 측 URL이라는 것이 칭의의 일부가되어서는 안된다고 생각합니다. – acjay

2

backbone-query-parameters 플러그인을 더 이상 사용할 필요가 없습니다. 최신 버전의 Backbone을 가지고 있는지 확인한 다음 loadUrl 메서드를 History.prototype 안에 덮어 씁니다.

// Regex to match search query strings 
var searchStripper = /\?.*$/g; 

// Attempt to load the current URL fragment. If a route succeeds with a 
// match, returns `true`. If no defined routes matches the fragment, 
// returns `false`. 
loadUrl: function(fragmentOverride) { 
    var fragment = this.fragment = this.getFragment(fragmentOverride); 
    fragment = fragment.replace(searchStripper, ''); // remove the search query parameter 
    var matched = _.any(this.handlers, function(handler) { 
    if (handler.route.test(fragment)) { 
     handler.callback(fragment); 
     return true; 
    } 
    }); 
    return matched; 
}, 
+0

이 또한 @TIMEX은 아마 그대로 쿼리 문자열을 유지하고자하는 초기 URL'사용자/111',에서 URL의 PARAMS을 제거하지 않습니다? 또한 쿼리 문자열이 조각의 일부가 아닌 해시 기반 URL을 사용할 때 문제를 해결하지 않습니다. – jevakallio

0

너무 늦었는지 확실하지 않습니다. 나는 같은 문제에 봉착했으며 확신을 갖고 말할 수있다. 이것은 백본 쿼리 매개 변수로 인한 버그이다.

사실은 귀하의 게시물에 의해 영감을 된. 현재 프로젝트의 초기 단계에서 백본 쿼리 매개 변수를 도입 했으므로 제대로 작동했습니다. 그러나 나중에 백본이 변경되어 백본 쿼리 매개 변수가 매개 변수를 더 이상 사용할 수 없습니다. 최근까지 저자가 백본 쿼리 매개 변수를 업그레이드 한 것으로 나타났습니다. 나는 그것을 다시 끌어 들였고, 효과가있었습니다.

그런 다음, 당신은 알고있다. 나는 같은 문제에 빠지며 정말로 좌절감을 느낀다. 저는 귀하의 게시물을 볼 때까지 백본 쿼리 매개 변수에 대해 의심하지 않았습니다.

나는 플러그인을 제거하고 지금 내 역사는 매력처럼 작동, 내 자신의 코드를 장착.

는 GET 매개 변수를 가져 오기 위해 여러 가지 방법이 있습니다. 내 것은 그 중 하나 일 뿐이지 만 그것은 나를 위해 일합니다. 참조 용으로 여기에 게시합니다.

getParams: -> 
    rtn = {} 

    if window.location.search.length > 0 
     queryStringRegex = /^\?(.*)/ 
     match = queryStringRegex.exec window.location.search 
     param_string = match[1] 

     if param_string.length > 0 
     params_array = param_string.split("&") 

     for value in params_array 
      temp = value.split("=") 
      rtn[temp[0]] = decodeURI(temp[1]) 

    rtn 

그냥 경우에, 내 노선이

"path(?*queryString)" : "pathAction" 
관련 문제