ব্যাকবোন.জেএস: বর্তমান রুট পান


137

ব্যাকবোন ব্যবহার করে, বর্তমান রুটের নামটি পাওয়া কি আমার পক্ষে সম্ভব? রুট পরিবর্তনের ইভেন্টগুলিতে কীভাবে আবদ্ধ থাকতে হয় তা আমি জানি তবে পরিবর্তনগুলির মধ্যে আমি অন্য সময়ে বর্তমান রুটটি নির্ধারণ করতে সক্ষম হতে চাই।


"নাম" দ্বারা আপনি কি সেই ফাংশনটি বোঝাতে চান যা সেই রুটটি বাঁধে বা ঠিক বর্তমান URL বা URL এর হ্যাশ অংশটি কী?
জন মুন্স ২

1
ওহ, হ্যাঁ, আমি আরও নির্দিষ্ট করা উচিত ছিল। আমি ফাংশনটির নাম জানতে চাই। (আমি কীভাবে অবস্থান.হ্যাশ বা ব্যাকবোন। হিস্টরি.ফ্র্যাগমেন্টটি করে URL এর হ্যাশ অংশ পেতে পারি তা জানি know)
ড্রইউ দারা-আব্রামস

উত্তর:


209

আপনি যদি আপনার অ্যাপ্লিকেশনটিতে একটি রাউটার ইনস্ট্যান্ট করেন তবে নিম্নলিখিত লাইনটি বর্তমান খণ্ডটি প্রদান করে:

Backbone.history.getFragment();

থেকে Backbone.js ডকুমেন্টেশন :

"[...] ইতিহাস একটি বিশ্বব্যাপী রাউটার (ফ্রেম প্রতি) হ্যান্ডেল hashchange ইভেন্ট বা pushState করার হিসেবে কাজ করে, যথাযথ রুট মেলে এবং ট্রিগার callbacks আপনি কি কখনো এই নিজের একটি তৈরি করতে থাকা উচিত নয় -। আপনি রেফারেন্স ব্যবহার করা উচিত আপনি যদি রাস্তাগুলির সাথে রাউটারগুলি ব্যবহার করেন তবে স্বয়ংক্রিয়ভাবে আপনার জন্য তৈরি হবে ব্যাকবোন হিস্টোরিতে [[...] "

আপনার যদি সেই খণ্ডটির সাথে আবদ্ধ ফাংশনটির নাম প্রয়োজন হয় তবে আপনি নিজের রাউটারের আওতায় এই জাতীয় কিছু তৈরি করতে পারেন:

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

বা আপনার রাউটারের বাইরে থেকে এটি পছন্দ করুন:

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

ধন্যবাদ, দুর্দান্ত। আমি ডকুমেন্টে ব্যাকবোন। হিস্টরি.ফ্র্যাগমেন্টের কোনও উল্লেখ মনে করি নি। এটি কি নতুন সংযোজন, বা কেবল বিনা প্রতিবন্ধী?
ড্র দারা-আব্রামস

আমি মনে করি এটি অনিবন্ধিত। আসলে, আমি এটি প্রথমবার কোথায় দেখলাম মনে নেই, কিছু ব্লগ বা সম্ভবত ব্যাকবোন উত্স কোড।
রবার্ট

25
এফওয়াইআই, এটি 'foo /: id' বা 'বার *
প্যারামস

2
আরও ভাল ব্যবহার Backbone.history.getFragment(), কারণ Backbone.history.fragmentএটি একটি ব্যক্তিগত লুকানো সম্পত্তি।
ভাদ

1
আমি @ ভ্যাডের পরামর্শ অনুসরণ করে উত্তরটি সংশোধন করেছি। আমি আর ব্যাকবোন ব্যবহার করছি না তবে তার মন্তব্যটি আমার কাছে ঠিক শোনা যাচ্ছে। (পূর্ববর্তী উত্তরটি ছিল: ব্যাকবোন হিস্ট্রি.সেটফ্রেগমেন্টের পরিবর্তে ব্যাকবোন। হিস্টোরি.ফ্রেগমেন্ট ())
রবার্ট

57

রবার্টের উত্তর আকর্ষণীয়, তবে দুঃখজনকভাবে এটি কেবল তখনই কাজ করবে যদি হ্যাশটিকে রুটে ঠিক যেমন সংজ্ঞায়িত করা হয়। উদাহরণস্বরূপ আপনার যদি কোনও রুট থাকে তবে user(/:uid)এটির সাথে বা (যদি উভয়ই এইরকম রুটের জন্য সবচেয়ে স্পষ্ট ব্যবহারের ক্ষেত্রে দুটি Backbone.history.fragmentহয়) এর সাথে মেলে না । অন্য কথায়, হ্যাশটি হুবহু হলে (এটি খুব কমই অসম্ভব) কেবলমাত্র উপযুক্ত কলব্যাকের নামটি খুঁজে পাবেন ।"user""user/1""user(/:uid)"

যেহেতু আমার এই কার্যকারিতাটির প্রয়োজন ছিল তাই আমি Backbone.Routerএকটি ফাংশন দিয়ে প্রসারিত currentকরেছি যা ইতিহাস এবং রাউটার অবজেক্টের কিছু কোড পুনরায় ব্যবহার করে উপযুক্ত কলব্যাকটি ট্রিগার করার জন্য সংজ্ঞায়িত রাউটের বিপরীতে বর্তমান খণ্ডটির সাথে মেলে। আমার ব্যবহারের ক্ষেত্রে এটি alচ্ছিক প্যারামিটার নেয় 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ভেরিয়েবলের প্রয়োজনীয়তা অপসারণ (@ ডানআব্রামভ এটি ইতিমধ্যে এটি করেছিলেন)।
চিহ্নিত করুন

@ মার্ক এই ভাল খবর। তবে আমি কীভাবে সামুদ্রিক ক্ষেত্রে এই বৈশিষ্ট্যটি ব্যবহার করতে পারি? ডক্সে এটি সম্পর্কে কিছুই নেই।
darksoulsong

2
@ দারডসৌলসং আপনি যদি ব্যবহার করেন Marionette.AppRouterতবে উপরের ফাংশনটি দিয়ে আপনার রাউটারটি প্রসারিত করুন, তবে বিকল্পের Router.appRoutesজন্য Router.routes
মার্ক

11

কল করা রুট হ্যান্ডলারের কাছ থেকে কলিং রুট (বা url) পেতে, আপনি এটি পরীক্ষা করে দেখতে পারেন

ব্যাকবোন। হিস্টরি.লোকেশন হিরিফ ... সম্পূর্ণ ইউআরএল
ব্যাকবোন। হিস্টরি.লোকেশন.সার্ক ... কোয়েরি স্ট্রিং শুরু হচ্ছে?

আমি এই উত্তরের সন্ধানে এখানে পৌঁছেছি তাই আমার ধারণা আমি যা পেয়েছি তা ছেড়ে দেওয়া উচিত।


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 (প্রস্তাবিত ও ডিফল্ট)।
ড্যান আব্রামভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.