Backbone.js: mevcut rotayı al


137

Omurga kullanarak geçerli rotanın adını almam mümkün mü? Rota değişikliği olaylarına nasıl bağlanacağımı biliyorum, ancak mevcut rotayı diğer zamanlarda, değişiklikler arasında belirleyebilmek istiyorum.


"Name" ile, söz konusu rotanın bağlandığı işlev mi yoksa URL'nin şu anki URL'si veya karma kısmı nedir?
John Munsch

1
Oh, evet, daha spesifik olmalıydım. İşlevin adını bilmek istiyorum. (URL'nin karma bölümünü location.hash veya Backbone.history.fragment yaparak nasıl edinebileceğimi biliyorum.)
Drew Dara-Abrams

Yanıtlar:


209

Uygulamanızda bir Yönlendirici başlattıysanız, aşağıdaki satır geçerli parçayı döndürür:

Backbone.history.getFragment();

Gönderen backbone.js belgelerinde :

"[...] Geçmiş, hashchange olaylarını veya pushState'i işlemek, uygun rotayı eşleştirmek ve geri çağrıları tetiklemek için global bir yönlendirici (kare başına) görevi görür. Bunlardan birini kendiniz oluşturmanız gerekmez - referansı kullanmalısınız Güzergahlar ile Yönlendiricilerden faydalanırsanız sizin için otomatik olarak oluşturulacak olan Backbone.history adresine gidin . [...] "

Bu parçaya bağlı işlevin adına ihtiyacınız varsa, Yönlendiricinizin kapsamı içinde böyle bir şey yapabilirsiniz:

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

Veya yönlendiricinizin dışından bu şekilde:

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

Teşekkürler, bu harika. Belgede hiç Backbone.history.fragment'ten bahsetmedim. Bu yeni bir ekleme mi, yoksa belgesiz mi?
Drew Dara-Abrams

Bence bu belgelenmemiş. Aslında, ilk kez nerede gördüğümü hatırlamıyorum, bazı bloglar veya belki de omurga kaynak kodu.
Robert

25
Bilginize, bu 'foo /: id' veya 'bar * params' gibi
yollarla çalışmaz

2
Daha iyi kullanım Backbone.history.getFragment(), çünkü Backbone.history.fragmentgizli bir özelliktir.
Vad

1
@Vad önerisini takiben cevabı düzelttim. Artık Omurga kullanmıyorum ama yorumu bana doğru geliyor. (Önceki cevap: Backbone.history.getFragment () yerine Backbone.history.fragment ())
Robert

57

Robert'ın cevabı ilginç, ama ne yazık ki sadece karma tam olarak rotada tanımlandığı gibi çalışacak. Örneğin, bir rotanız user(/:uid)varsa, ya ( Backbone.history.fragmentya "user"da "user/1"her ikisi de bu rota için en belirgin iki kullanım örneğidir ) eşleşmez. Başka bir deyişle, yalnızca karma tamsa "user(/:uid)"(çok düşük olasılıkla) uygun geri arama adını bulur .

Bu işlevselliğe ihtiyaç duyduğumdan , Tarih ve Yönlendirici nesnesinin geçerli parçayı uygun geri çağırma için tetiklenen tanımlı Rotalara karşı eşleştirmek için kullandığı kodun bir kısmını yeniden kullanan Backbone.Routerbir current-fonksiyonu ile genişletilmiş . Kullanım durumum için, routedoğru olan herhangi bir şeye ayarlanırsa, rota için tanımlanan ilgili işlev adını döndürecek olan isteğe bağlı parametreyi alır . Aksi takdirde mevcut karma parçasını döndürür Backbone.History.fragment.

Kodu, Omurga yönlendiricisini başlattığınız ve ayarladığınız mevcut Extend'inize ekleyebilirsiniz.

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'

Eminim bazı iyileştirmeler yapılabilir, ancak bu, başlamanız için iyi bir yoldur. Ayrıca, Route nesnesini genişletmeden bu işlevselliği oluşturmak kolaydır. Bunu yaptım çünkü kurulumum için en uygun yol buydu.

Bunu henüz tam olarak test etmedim, bu yüzden bir şey güneye giderse lütfen bana bildirin.


GÜNCELLEME 04/25/2013

İşlevde bazı değişiklikler yaptım, bu yüzden karma veya rota geri arama adı döndürmek yerine, rotadan alacağınız gibi geçerli rotadaki tüm verilere erişebilmeniz için parça, params ve rota içeren bir nesne döndürüyorum. Etkinlik.

Aşağıdaki değişiklikleri görebilirsiniz:

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
    };
}

Daha fazla yorum ve açıklama için önceki koda bakın, çoğunlukla aynı görünüyorlar.


1
Bunu kendim yazmak üzereydim, ama önce çözüm için Googled. Yaptığım için memnunum. Seninki tam olarak istediğimi yapıyor, teşekkürler!
Dan Abramov

İşte ilk bakışta anlaşılması daha kolay olduğuna inandığım biraz daha ayrıntılı bir versiyon .
Dan Abramov

4
Vay, bunun için teşekkürler! Kod tabanımızda bir onay aldınız. ; P Marionette için hafifçe ayarladık. Bu arada, bir kısayol _.findolarak this, işlevin üçüncü parametresini (bağlamı ayarlar) olarak ayarlayabilirsiniz , böylece Routerdeğişken gereksinimini ortadan kaldırırsınız (@DanAbramov bunu zaten yaptı).
Mark

@Mark Bunlar iyi haberler. Ancak bu özelliği kuklada nasıl kullanabilirim? Belgelerde bununla ilgili hiçbir şey yok.
darksoulsong

2
Eğer kullanıyorsanız @darksoulsong Marionette.AppRouteryukarıdaki fonksiyonu, ancak yerine ile yönlendirici uzatmak Router.appRoutesiçin Router.routes.
Mark

11

Aranan rotayı (veya url) çağrılan rota işleyiciden almak için, kontrol ederek alabilirsiniz

Omurga.tarih.konumu.href ... tam URL
Backbone.history.location.search ... sorgu dizesi başlıyor mu?

Bu cevabı bulmak için buraya geldim, sanırım bulduğum şeyi bırakmalıyım.


6

Yönlendirici için kök ayarını kullanırsanız, 'gerçek' parçayı almak için bunu da ekleyebilirsiniz.

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

6

İşte Simon'un cevabının biraz daha ayrıntılı (veya zevkinize bağlı olarak daha okunabilir) versiyonu :

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
    };
  }
}

4

Kaynağına bakarsanız Router, yönlendirici bir şeyin değiştiğini söyleyerek olayı tetiklediğinde, adı "route: name" olarak geçirdiğini görürsünüz.

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

"Rota" olayını her zaman yönlendiriciye bağlayabilir ve geçerli rotayı almak için saklayabilirsiniz.


Tamam, sanırım bu bir "kendin yap" türü.
Drew Dara-Abrams

Evet ama almazsınız routeeğer olay trigger değil true (önerilir & varsayılan).
Dan Abramov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.