web-dev-qa-db-ja.com

クエリ文字列でルートをナビゲートする

Backbone.Router.navigatetesttrueに設定します:

var test = false;

var Router = Backbone.Router.extend({
  routes: {
    'posts': 'showPosts'
  },
  showPosts: function () {
    test = true;
  }
});

router = new Router();
Backbone.history.start();

router.navigate('posts?foo=3', {trigger: true});

assert.ok(test);

たとえば、posts?foo=3フラグメントはデフォルトでpostsルートに一致しますか、それとも別のルートを設定する必要がありますか。たとえば、posts?*querystring

ありがとうございました

PS: backbone-query-parameters が存在することは知っていますが、バックボーンについてだけ知りたいです。

36
abernier

その期待されるパラメータで別のルートを追加する必要があります:

routes: {
    'posts?foo=:foo' : 'showPosts',
    'posts': 'showPosts'
},
showPosts: function (foo) {
    if(typeof foo != 'undefined'){
       // foo parameters was passed
    }
    test = true;
}

update
一般的なルートを定義して、すべてのクエリ文字列を返し、ハンドラーで解析することができます。

routes: {
   'posts': 'showPosts',
   'posts?*queryString' : 'showPosts'
},
showPosts: function (queryString) {
    var params = parseQueryString(queryString);
    if(params.foo){
        // foo parameters was passed
    }
}  
...
// and the function that parses the query string can be something like : 
function parseQueryString(queryString){
    var params = {};
    if(queryString){
        _.each(
            _.map(decodeURI(queryString).split(/&/g),function(el,i){
                var aux = el.split('='), o = {};
                if(aux.length >= 1){
                    var val = undefined;
                    if(aux.length == 2)
                        val = aux[1];
                    o[aux[0]] = val;
                }
                return o;
            }),
            function(o){
                _.extend(params,o);
            }
        );
    }
    return params;
}

update 2

ここに ライブデモ があり、動作中のコードを確認できます。

66
gion_13

次のように、同じコールバックを持つ2つのルートを定義する代わりに、前の回答を補完するだけです。

routes: {
    'posts': 'showPosts',
    'posts?*querystring': 'showPosts'
}

コードを簡潔に保つためのルートは1つだけです。

routes: {
    'posts(?*querystring)': 'showPosts'
}
18
romaia

バックボーンドキュメント:

ルートには、パラメーター部分、:paramを含めることができます。これは、スラッシュ間の単一のURLコンポーネントに一致します。スプラットパーツ* splatは、任意の数のURLコンポーネントと一致できます。

それでも一致せずに機能を維持したい場合は、2つのルートを定義できます

routes: {
  'posts': 'showPosts',
  'posts?*querystring': 'showPosts'
}

showPosts: function(querystring) {
  if (querystring) {
    // here you can parse your querystring, for your case the querystring variable is 
    // 'foo=3'
  }
  //here you'll show posts according to the querystring (or lack thereof)      
}
6
jakee

まだlodash(アンダースコア)を使用している別のテイクがあります。 _.mapを削除し、変数に少し冗長性を追加し、先頭の「?」を削除しました存在する場合:

function parseQueryString(queryString)
{
    if (!_.isString(queryString))
        return
    queryString = queryString.substring( queryString.indexOf('?') + 1 )
    var params = {}
    var queryParts = decodeURI(queryString).split(/&/g)
    _.each(queryParts, function(val)
        {
            var parts = val.split('=')
            if (parts.length >= 1)
            {
                var val = undefined
                if (parts.length == 2)
                    val = parts[1]
                params[parts[0]] = val
            }
        })
    return params
}
5
blented

RFC 3986「URIの構文」は、クエリパラメータのホールドがハッシュフラグメントの前に来ることを示しています。

URIでは、ハッシュマークはURLの末尾近くにオプションのフラグメントを導入します。 URIの汎用RFC 3986構文では、疑問符?によって導入されるオプションのクエリ部分も許可されます。クエリとフラグメントを持つURIでは、フラグメントはクエリに従います。

サーバーから取得しているリダイレクト、つまり「 http://foo.com/main.html?error=errormessage#site 」を処理するこの問題があります。クエリをルーティングしたいのですが、このURLを処理するバックボーンルート式を記述する方法がわかりません。今のところは、ハッシュにルーティングして、location.searchを解析してクエリをチェックします。

1
Chris Collins