Backbone.js: वर्तमान मार्ग प्राप्त करें


137

बैकबोन का उपयोग करना, क्या मेरे लिए वर्तमान मार्ग का नाम प्राप्त करना संभव है? मुझे पता है कि परिवर्तन की घटनाओं को कैसे रूट करना है, लेकिन मैं बदलावों के बीच, वर्तमान मार्ग को अन्य समय में निर्धारित करने में सक्षम होना चाहूंगा।


"नाम" से क्या आपका तात्पर्य उस फ़ंक्शन से है, जो उस मार्ग से जुड़ता है या URL का वर्तमान URL या हैश भाग क्या है?
जॉन मुन्सच

1
ओह, हाँ, मुझे और अधिक विशिष्ट होना चाहिए था। मैं फंक्शन का नाम जानना चाहूंगा। (मुझे पता है कि URL का हैश भाग कैसे प्राप्त करें। स्थान या बैकबोन .history.fragment।)
ड्रू दारा-अब्राम

जवाबों:


209

यदि आपने अपने आवेदन में एक राउटर को तत्काल बदल दिया है, तो निम्न पंक्ति वर्तमान टुकड़ा लौटाती है:

Backbone.history.getFragment();

से Backbone.js प्रलेखन :

"[...] इतिहास एक वैश्विक राउटर (प्रति फ्रेम) के रूप में हैशचेंज घटनाओं या पुशस्टेट को संभालने, उपयुक्त मार्ग से मेल खाने और कॉलबैक को ट्रिगर करने के लिए कार्य करता है। आपको कभी भी इनमें से किसी एक को नहीं बनाना चाहिए - आपको संदर्भ का उपयोग करना चाहिए। यदि आप मार्गों के साथ मार्गों का उपयोग करते हैं तो Backbone.history आपके लिए स्वचालित रूप से बनाया जाएगा । [...] "

यदि आपको उस टुकड़े से जुड़े फ़ंक्शन के नाम की आवश्यकता है, तो आप अपने राउटर के दायरे के अंदर कुछ ऐसा बना सकते हैं:

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

या अपने राउटर के बाहर से इसे पसंद करें:

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

धन्यवाद, यह बहुत अच्छा है। मैंने दस्तावेज़ में Backbone.history.fragment का कोई उल्लेख नहीं किया है। क्या यह एक नया जोड़ है, या सिर्फ अनिर्दिष्ट है?
ड्रू दारा-अब्राम्स

मुझे लगता है कि यह अनिर्दिष्ट है। असल में, मुझे याद नहीं है कि मैंने इसे पहली बार कहाँ देखा था, कुछ ब्लॉग या शायद रीढ़ स्रोत कोड।
रॉबर्ट

25
FYI करें, यह 'foo /: id' या 'bar * params' जैसे मार्गों के साथ काम नहीं करता है
wprl

2
बेहतर उपयोग Backbone.history.getFragment(), क्योंकि Backbone.history.fragmentएक निजी छिपी हुई संपत्ति है।
वड

1
मैंने @Vad सुझाव के बाद उत्तर को सही किया है। मैं अब बैकबोन का उपयोग नहीं कर रहा हूं, लेकिन उनकी टिप्पणी मुझे सही लगती है। (पिछला जवाब था: Backbone.history.fragment के बजाय Backbone.history.getFragment ())
रॉबर्ट

57

रॉबर्ट का जवाब दिलचस्प है, लेकिन दुख की बात है कि यह केवल तभी काम करेगा जब हैश बिल्कुल मार्ग में परिभाषित हो। यदि आपके पास उदाहरण के लिए एक मार्ग है तो user(/:uid)इसका मिलान नहीं किया जाएगा यदि वह Backbone.history.fragmentहै "user"या "user/1"(दोनों जो कि ऐसे मार्ग के लिए दो सबसे स्पष्ट उपयोग के मामले हैं)। दूसरे शब्दों में, यह केवल उचित कॉलबैक नाम खोजेगा यदि हैश बिल्कुल "user(/:uid)"(अत्यधिक संभावना नहीं) है।

के बाद से मैं इस कार्यक्षमता की जरूरत मैं बढ़ाया Backbone.Routerएक साथ currentसमारोह है कि उपयुक्त कॉलबैक ट्रिगर के लिए परिभाषित मार्गों के खिलाफ वर्तमान खंड से मेल खाती कोड के कुछ इतिहास और रूटर वस्तु उपयोग पुनः उपयोग कर लेता। मेरे उपयोग के मामले के लिए, यह वैकल्पिक पैरामीटर लेता है route, जो अगर किसी भी चीज़ के लिए सेट किया गया है, तो वह रूट के लिए परिभाषित संबंधित फ़ंक्शन नाम को लौटा देगा। अन्यथा यह वर्तमान हैश-टुकड़ा से वापस आ जाएगा Backbone.History.fragment

आप अपने मौजूदा विस्तार में कोड जोड़ सकते हैं जहां आप बैकबोन राउटर को इनिशियलाइज़ और सेटअप करते हैं।

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'

मुझे यकीन है कि कुछ सुधार किए जा सकते हैं, लेकिन आपको शुरू करने का यह एक अच्छा तरीका है। इसके अलावा, रूट-ऑब्जेक्ट को बढ़ाए बिना इस कार्यक्षमता को बनाना आसान है। मैंने ऐसा किया क्योंकि यह मेरे सेट-अप के लिए सबसे सुविधाजनक तरीका था।

मैंने अभी तक इसका पूरी तरह से परीक्षण नहीं किया है, इसलिए कृपया मुझे बताएं कि क्या कुछ दक्षिण में जाता है।


अद्यतन 04/25/2013

मैंने फ़ंक्शन में कुछ बदलाव किए हैं, इसलिए या तो हैश या रूट कॉलबैक नाम पर लौटने के बजाय, मैं खंड, परम और मार्ग के साथ एक वस्तु लौटाता हूं ताकि आप वर्तमान मार्ग से सभी डेटा तक पहुंच सकें, जैसे आप रूट से करेंगे- प्रतिस्पर्धा।

आप नीचे परिवर्तन देख सकते हैं:

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

आगे की टिप्पणियों और स्पष्टीकरणों के लिए पिछले कोड देखें, वे ज्यादातर समान दिखते हैं।


1
यह स्वयं लिखने के बारे में था, लेकिन पहले समाधान के लिए गूगलेड। खुशी है कि मैंने किया। तुम्हारा वही करता है जो मैं चाहता था, धन्यवाद!
दान अब्रामोव

यहाँ थोड़ा अधिक वर्बोज़ संस्करण है जो मुझे लगता है कि पहली नज़र में समझना आसान है।
दान अब्रामोव

4
वाह, इसके लिए धन्यवाद! आपको अभी हमारे कोडबेस में पावती मिली है। ; हमने मारिओनेट के लिए इसे थोड़ा ट्विक किया। वैसे, एक शॉर्टकट के रूप, आप तृतीय पैरामीटर के (सेट संदर्भ) सेट कर सकते हैं _.findके रूप में कार्य thisहै, इस प्रकार की आवश्यकता को समाप्त Routerचर (@DanAbramov यह पहले से ही किया था)।
मार्क

@ मर्क ये अच्छी खबर हैं। लेकिन मैं इस सुविधा का उपयोग कैसे कर सकता हूं? डॉक्स में इसके बारे में कुछ भी नहीं है।
अंधेरी 24

2
@darksoulsong यदि आप उपयोग कर रहे हैं Marionette.AppRouter, तो ऊपर दिए गए फ़ंक्शन के साथ अपने राउटर का विस्तार करें, लेकिन इसके Router.appRoutesलिए विकल्प Router.routes
मार्क

11

कॉलिंग रूट (या url) को रूट रूट हैंडलर से प्राप्त करने के लिए, आप इसे चेक करके प्राप्त कर सकते हैं

Backbone.history.location.href ... पूर्ण url
Backbone.history.location.search ... क्वेरी स्ट्रिंग से शुरू हो रहा है?

मैं इस उत्तर की तलाश में यहां आया था इसलिए मुझे लगता है कि मुझे जो कुछ मिला है उसे छोड़ देना चाहिए।


6

यदि आप राउटर के लिए रूट सेटिंग का उपयोग करते हैं, तो आप इसे 'वास्तविक' टुकड़ा प्राप्त करने के लिए भी शामिल कर सकते हैं।

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

6

यहां साइमन के उत्तर का एक बालक अधिक वर्बोज़ (या, आपके स्वाद, अधिक पठनीय) संस्करण पर निर्भर करता है :

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

यदि आप स्रोत के लिए स्रोत को Routerदेखते हैं, तो आप देखेंगे कि जब राउटर घटना को यह कहते हुए ट्रिगर करता है कि कुछ परिवर्तन होता है, तो यह नाम को "मार्ग: नाम" के रूप में पास करता है।

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

आप हमेशा राउटर पर "रूट" इवेंट को हुक कर सकते हैं और इसे वर्तमान रूट प्राप्त करने के लिए स्टोर कर सकते हैं।


ठीक है, मुझे लगता है कि यह एक "अपने आप को बनाया हुआ" है।
ड्रू दारा-अब्राम्स

routeयदि trigger आप true (अनुशंसित और डिफ़ॉल्ट) नहीं है, तो हाँ, लेकिन आपको घटना नहीं मिलेगी ।
दान अब्रामोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.