13

Backbone pushstate を使用していて、クエリ パラメータを含むページに移動するとします。

domain.com/user/111?hello=123

これを実行すると:

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

設定ページは完全に読み込まれますが、?hello=123 が URL に残っています...

domain.com/settings?hello=123

そして、そのクエリパラメーターは、サイトをナビゲートするすべての場所で URL に残ります...

4

3 に答える 3

19

バックボーン ルーティングとクエリ パラメータは、不幸な組み合わせです。問題は、この GitHub の問題に詳しく記載されています。

核となる問題は、Backbone.RouterURL ハッシュ フラグメントと pushState API で動作するように設計されていることです。ハッシュ URL を使用する場合、クエリ文字列はハッシュに先行し、ルートで一致することはありません。pushState では、クエリ文字列は URL フラグメントの一部であり、別のルート式が必要です。

routesearchがあり、その route はオプションでパラメータq,sortおよびtype. 次のようなクエリ文字列として:

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"

これにより、サードパーティのクエリ文字列ライブラリやブラウザーの互換性について心配する必要がなくなります。私に言わせれば、後者のタイプの URL もすっきりしているように見えます。

于 2013-03-04T13:49:48.740 に答える
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;
},
于 2013-03-03T23:58:59.883 に答える
0

手遅れかどうかはわかりません。私は同じ問題に遭遇しましたが、自信を持って言えます。これは、backbone-query-parameters が原因のバグです。

私は実際にあなたの投稿に触発されました。現在のプロジェクトの初期段階で、backbone-query-parameters を導入しましたが、うまく機能しました。しかし、後でバックボーンがいくつかの変更を加えたため、backbone-query-parameters はパラメーターを取得できなくなりました。最近まで、著者が backbone-query-parameters をアップグレードしていることに気付きました。もう一度引っ張ったところ、うまくいきました。

それから、あなたは知っています。私は同じ問題に直面し、本当にイライラしています。あなたの投稿を見るまで、backbone-query-parameters について疑うことはありませんでした。

プラグインを削除し、独自のコードを装備したので、履歴が魅力的に機能するようになりました。

get パラメータを取得するには、さまざまな方法があります。私はそれらの1つにすぎませんが、それは私のために仕事をします. ご参考までに、ここに掲載します。

  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"
于 2013-04-04T06:57:33.523 に答える