2011-10-13 13 views
35

के साथ मॉड्यूलर किए गए विचारों के माध्यम से नेविगेट करने के लिए Backbone.js राउटर का उपयोग करके मैं अपने विचारों और राउटर को अलग-अलग फ़ाइलों में अलग-अलग कर रहा हूं। मेरे पास एक main.js फ़ाइल है जो राउटर को तुरंत चालू करती है, और मेरा डिफ़ॉल्ट दृश्य भी प्रस्तुत करती है।require.js

मेरे राउटर ने ('देखें /: आईडी') देखा है और संपादित करें ('संपादित करें/आईडी') मार्ग के रूप में। Main.js में, जब मैं राउटर को तुरंत चालू करता हूं, तो मैं router.navigate ('देखें/1', सत्य) हार्डकोड कर सकता हूं और नेविगेशन ठीक काम करता है। मेरी दृश्य फ़ाइल में, जब मैं संपादन लिंक पर क्लिक करता हूं, तो मैं राउटर.नाविगेट ('व्यू /' + आईडी, सत्य) को कॉल करना चाहता हूं, लेकिन मुझे यकीन नहीं है कि मुझे यह कैसे करना चाहिए।

मुझे बैकबोन.history.navigate ('व्यू /' + आईडी, सच) कॉल करने में सफलता मिली है, लेकिन मुझे नहीं लगता कि मुझे वैश्विक बैकबोन ऑब्जेक्ट पर भरोसा करना चाहिए।

मैंने अपने विचारों में ({राउटर: एपराउटर}) पारित करने का प्रयास किया ताकि मैं इस .options.router.navigate() का उपयोग कर सकूं, हालांकि यह मेरे लिए काम नहीं कर रहा था।

रूटर:

define(['./View', './Edit'], function (View, Edit) { 
    return Backbone.Router.extend({ 
     routes: { 
      'View/:id': 'view', 
      'Edit/:id': 'edit' 
     }, 

     view: function (id) { 
      var model = this.collection.get(id); 
      var view = new View({ model: model }); 
      view.render(); 
     }, 

     edit: function (id) { 
      var model = this.collection.get(id); 
      var edit = new Edit({ model: model }); 
      edit.render(); 
     } 
    }); 
}); 

दृश्य:

define(function() { 
    return Backbone.View.extend({ 
     template: Handlebars.compile($('#template').html()), 

     events: { 
      'click .edit': 'edit' 
     }, 

     render: function() { 
      //Create and insert the cover letter view 
      $(this.el).html(this.template(this.model.toJSON())); 
      $('#View').html(this.el); 

      return this; 
     }, 

     edit: function() { 
      Backbone.history.navigate('Edit/' + this.model.id, true); 
     }, 
    }); 
}); 
+0

हाय मैन, मैं आपके जैसे कुछ ऐसा कर रहा हूं, जो मेरे व्यू मॉड्यूल में router.navigate() का उपयोग करने का इरादा रखता है। और अंत में आप इसे कैसे प्राप्त किया? अग्रिम में Thx बहुत ज्यादा। – chaonextdoor

+4

मैं बैकगोन.history.navigate का उपयोग कर समाप्त हुआ। चूंकि मैं विचारों, राउटर और मॉडलों के लिए अलग-अलग फ़ाइलों में अपने विचारों को अलग कर रहा हूं, और उन्हें लोड करने के लिए require.js का उपयोग कर रहा हूं। राउटर, या मेरे सभी विचारों पर एक ईवेंट ऑब्जेक्ट पास करने में बहुत अधिक परेशानी थी। ग्लोबल सबसे ज्यादा समझ में आया, क्योंकि बैकबोन पहले से ही वैश्विक नामस्थान में था। – MrGrigg

+1

तो backbone.history.navigate router.navigate के बराबर है? – chaonextdoor

उत्तर

20

किसी भी बैकबोन प्रश्न के साथ, इसे संभालने के कई तरीके हैं।

var MyNamespace = {}; 

MyNamespace.init = function() { 
    MyNamespace.appView = new MyAppView(); 
    MyNamespace.router = new MyRouter(); 
    // etc 
} 

दृश्य तो MyNamespace.router आवश्यक के रूप में करने का उल्लेख कर सकते हैं: जिस तरह से मैं अपने वर्तमान प्रोजेक्ट में यह दरवाजा खटखटाया एक वैश्विक कस्टम नाम स्थान में सब कुछ डाल करने के लिए, और कहा कि का उपयोग आवश्यक संदर्भ के आसपास पारित करने के लिए किया गया था। लेकिन यह इस तरह से काम नहीं चलेगा लग रहा है/require.js साथ प्रोत्साहित नहीं किया जाता है, इसलिए यहां कुछ अन्य विकल्प हैं:

  • कभी स्पष्ट रूप से रूटर फोन न करें - इसके बजाय, एक वैश्विक स्थिति ऑब्जेक्ट को बदलने कि राउटर सुनता है। वास्तव में यह है कि मैंने अपने वर्तमान प्रोजेक्ट में चीजें कैसे की हैं - अधिक जानकारी के लिए this response देखें।

  • अपने शीर्ष-स्तरीय दृश्य में राउटर संलग्न करें, जिसे अक्सर AppView कहा जाता है, इसे वैश्विक रूप से सुलभ बनाते हैं, और AppView.router.navigate() का उपयोग करें।

  • एक और मॉड्यूल बनाएं जो navigate उपयोगिता फ़ंक्शन प्रदान करता है जो आंतरिक रूप से Backbone.history.navigate() पर कॉल करता है।यह आपके द्वारा किए जा रहे कार्यों से बहुत अलग नहीं है, लेकिन यह थोड़ा और मॉड्यूलर बना देगा और आपको हर समय वैश्विक संदर्भ का उपयोग करने से रोक देगा। यह आपको आंतरिक कार्यान्वयन को बदलने की अनुमति देता है।

+0

क्या आप MyNamespace को मॉड्यूल की आवश्यकता के बाहर घोषित कर रहे हैं? यह वैश्विक बैकबोन ऑब्जेक्ट का उपयोग करने के करीब है, बस अपनी खुद की वस्तु के साथ, है ना? – MrGrigg

+0

मैं require.js का उपयोग नहीं कर रहा हूं, इसलिए यह मेरे मामले में लागू नहीं होता है। मुझे लगता है कि मेरी सूची में आखिरी गोली शायद requ.js idiom के सबसे नज़दीक है। – nrabinowitz

+0

हाँ, नेविगेट करने के लिए मेरी अपनी उपयोगिता इतनी बुरा विचार नहीं है। अगर मैं ऐसा करना चाहता था, तो शायद मैं एक ही उपयोगिता को अपने राउटर को एक विकल्प के रूप में पेश कर सकता था, शायद यह पूरी चीज को हल करेगा। – MrGrigg

8

आप इसे कर सकता है पुराने जमाने रास्ता

मामले में आप उत्सुक हैं, यहाँ मेरे एप्लिकेशन से कोड का एक समूह है window.location.hash :)

window.location.hash = "Edit/1" 

यदि आपको स्पष्ट मार्गों की आवश्यकता नहीं है तो यहां एक वैकल्पिक समाधान है। आप एप्लिकेशन को एक वस्तु है कि रीढ़ घटनाक्रम

window.EventDispatcher = _.extend({}, Backbone.Events); 

तब कहीं भी फैली हुई है में बनाने शुरू होता है जब आप आप भी कहीं भी घटना प्रेषण से, data नीचे किसी भी आप पैरामीटर हैं घटनाओं

EventDispatcher.bind("mymodel:edit", this.editHandler, this); 

के लिए सुनने और कर सकते हैं एप्लिकेशन सवारी

EventDispatcher.trigger("mymodel:edit", data); 
+0

मैंने पाया कि विंडो बैकबोन ऑब्जेक्ट का उपयोग करने से पहले मैंने विंडो.लोकेशन का उपयोग करने की कोशिश की, लेकिन यह वास्तव में मेरी घटनाओं को फायर नहीं कर रहा था, जो शायद एक पूरी तरह से अलग समस्या है। – MrGrigg

+0

यदि आप केवल ईवेंट ट्रिगर करने के लिए मार्गों का उपयोग कर रहे हैं (आपको स्पष्ट रूप से बदलने के लिए यूआरएल की आवश्यकता नहीं है, या उपयोगकर्ता के लिए बैक/फॉरवर्ड बटन का उपयोग करने के लिए), तो मुझे दोपहर का पता लगाने में मदद मिल सकती है। आप एक वैश्विक 'EventDispatcher' बना सकते हैं जिसे मैंने ऊपर दिए गए मेरे उत्तर में जोड़ा था। – kreek

+0

धन्यवाद क्रीक। मैं यूआरएल को इस विशेष ऐप के लिए मायने रखता हूं, मैं आगे और पीछे गया हूं। मैंने आपके वैश्विक ईवेंट प्रेषक के समान कम से कम एक अन्य उदाहरण देखा है। आपकी सहायता के लिए धन्यवाद. – MrGrigg

32

यदि कोई और इस समस्या का समाधान ढूंढ रहा है, तो मैं पोस्ट कर रहा हूं जो मैं कर रहा हूं। यदि आप बॉयलरप्लेट बैकबोन.जेएस का उपयोग कर रहे हैं, तो आपके पास में initialize() फ़ंक्शन होगा। मैं अपने initialize() समारोह निम्नलिखित की तरह लग रहे करने के लिए संशोधित: विरासत का backbone.js की विशेष स्वाद

initialize = function() { 
    var app_router; 
    app_router = new AppRouter(); 

    // Extend the View class to include a navigation method goTo 
    Backbone.View.goTo = function (loc) { 
    app_router.navigate(loc, true); 
    }; 

    Backbone.history.start(); 
}; 

के कारण, इस की अनुमति देता है मुझे मेरे विचारों में से किसी के भीतर से MyView.goTo(location); कॉल करने के लिए अनुमति देता है।

+9

मुझे 'Backbone.View.prototype.goTo =' –

+0

का उपयोग करना था, क्या आप इसे सफलतापूर्वक कॉलबैक में देख सकते हैं या आप इसके बारे में कैसे जाएंगे? यहां मेरा प्रश्न है यदि आप उस कोड को देखना चाहते हैं जिसका मैं जिक्र कर रहा हूं ... http://stackoverflow.com/questions/19472777/clear-localstorage-and-change-the-view-backbone – Lion789

+0

बहुत ही सुरुचिपूर्ण समाधान ! इसके लिए बहुत - बहुत धन्यवाद। मैंने किसी अन्य फ़ंक्शन के लिए बैकबोन.व्यू.प्रोटोटाइप का उपयोग किया है लेकिन यह मेरे दिमाग में नहीं आया है। – digaomatias

5

मेरे लिए, गोटो समारोह के साथ समाधान एक मामूली बदलाव

Backbone.View.prototype.goTo = function (loc) { 
     appRouter.navigate(loc, true); 
    }; 
3

मैं जानता हूँ कि इस सवाल पुराना है के साथ काम किया है, लेकिन मैं सोच रहा हूँ क्यों है आप रूटर प्राप्त करने के लिए require.js का उपयोग नहीं :

define(['./PathToRouter', ], function (router) { 
    return Backbone.View.extend({ 
     template: Handlebars.compile($('#template').html()), 

     events: { 
      'click .edit': 'edit' 
     }, 

     render: function() { 
      //Create and insert the cover letter view 
      $(this.el).html(this.template(this.model.toJSON())); 
      $('#View').html(this.el); 

      return this; 
     }, 

     edit: function() { 
      router.navigate('Edit/' + this.model.id, true); 
     } 
    }); 
}); 
+0

मुझे नहीं पता कि मैंने इस बारे में क्यों नहीं सोचा था। मेरे द्वारा किए गए अधिकांश कामों के लिए मार्गों की आवश्यकता नहीं है इसलिए मैंने कुछ समय तक इसका पुनरीक्षण नहीं किया है। मुझे खुशी है कि आप हालांकि चिंतित हैं। – MrGrigg

+2

उपरोक्त उदाहरण में, ./PathToRouter राउटर का उदाहरण नहीं है लेकिन एक वर्ग परिभाषा है। एक रीढ़ की हड्डी राउटर की एकमात्र स्थैतिक विधि कोई नेविगेट नहीं है! – LarZuK

+0

@LarZuK मैं अब तक इस समस्या से हटा हूं कि मैंने इसके बारे में भी नहीं सोचा था, लेकिन आप पूरी तरह से सही हैं। – MrGrigg

2

इस दृष्टिकोण के बारे में क्या? चूंकि रीढ़ की हड्डी अपने सभी 4 घटकों में टेम्पलेट पैटर्न लागू करती है, थोड़ी सी डिज़ाइन के साथ आप प्रत्येक दृश्य को किसी भी परिपत्र संदर्भ के बिना ऐप के राउटर के माध्यम से एक आसान नेविगेशन तंत्र प्रदान कर सकते हैं (यह कुछ अन्य पोस्टों में मैंने देखा था, लेकिन इसे टालने का प्रयास करें)।

रूटर घटक, नहीं बहुत अलग से अन्य रूटर उदाहरण के लिए:

define('Router', ['backbone', ... ], 
     function (Backbone, ...) { 

      var MyRouter = Backbone.Router.extend({ 
       routes: { 
        'viewA': 'viewA', 
        'viewB': 'viewB' 
       }, 

       initialize: function() { 
        ... 
       }; 
      }, 
      viewA: function() { 
       ... 
      }, 

      viewB: function() { 
       ... 
      } 
}); 

return MyRouter; 
}); 

अनुप्रयोग, रूटर उदाहरण बनाता है और इस उदाहरण गुजर पहला दृश्य आग:

define('App', ['backbone', ... 
], function (Backbone, ...) { 

    function initialize() { 

     //route creation 
     if (!this.routes) 
      routes = new Router(this); 
     //backbone history start 
     Backbone.history.start(); 

     //ViewA navigation, bigbang 
     if (!this.viewA) 
      this.viewA = new ViewA({router: this.routes}); 
     this.viewA.render(); 
    } 

    return { 
     initialize: initialize 
    }; 
}); 

BaseView, आधार निर्माता परिभाषा सभी विचारों और एक नेविगेशन विधि के लिए:

define('BaseView', ['jquery', 'underscore', 'backbone', ... 
], function ($, _, Backbone, ...) { 
    var BaseView; 

    BaseView = Backbone.View.extend({ 
     id: '...', 

     constructor: function (options) { 
      this.router = options.router; 
      this.model = options.model; 
      Backbone.View.prototype.constructor.call(this); 
     }, 
     initialize: function() { 
      this.template = _.template(tpl); 
     }, 

     events: { 

     }, 
     render: function() { 
      $(this.el).html(this.template()); 

      return this; 
     }, 
     //Provides transparent navigation between views throught the backbonejs 
     //route mechanism 
     navigate: function(pageId) 
     { 
      this.router.navigate(pageId, {trigger: true}); 
     } 
    }); 

    return BaseView; 
}); 

एक दृश्य उदाहरण के लिए, प्रत्येक दृश्य के आधार रीढ़ की हड्डी के बजाय एक से फैली हुई है, और आधार व्यवहार विरासत:

define('ViewA', ['jquery', 'underscore', 'backbone', 'BaseView' 
], function ($, _, Backbone, BaseView) { 
    var ViewA; 

    ViewA = BaseView.extend({ 
     id: '...', 

     constructor: function (options) { 
      this._super("constructor"); 
     }, 

     ... 
     foo: function() 
     { 
      ... 

      this.navigate("viewB"); 
     } 
    }); 

    return ViewA; 
}); 

यह मेरे लिए काम करता है, और यह भी कि यह अन्य परियोजनाओं में पुन: उपयोग किया जा सकता है।

1

मेरे लिए मैंने इस तरह के मुख्य एप्लिकेशन में एक ऑब्जेक्ट जोड़ा;

define(['jquery','underscore','backbone','views/personView','views/peopleView','views/textView'],function($,_,backbone,PersonView,PeopleView,TitleView){ 

    var Router = Backbone.Router.extend({ 
      routes:{ 
       '':'home', 
       'edit/:id':'editPerson', 
       'new':'editPerson', 
       'delete/:id':'deletePerson' 
       } 
      }) 

       var initialize = function(){ 

       var router = new Router(); 

       window.app = { 
        router:router 
        } 

     router.on('route:home',function(){ 


    }) 

      //enable routing using '#'[hashtag] navigation 
     Backbone.history.start(); 

      }; 

      return { 
      initialize:initialize 
      }; 

}); 

और आपके विचार के अंदर, आप windows.app.router.navigate कह सकते हैं ({ ', ट्रिगर: सच})। पता नहीं है कि इस मामले में वैश्विक स्कोपिंग अच्छा अभ्यास है, लेकिन यह मेरे लिए काम करता है।

0

मेरे पास एएमडी मॉड्यूल को रूट करने के लिए एक नया समाधान है।

RequireJS रूटर https://github.com/erikringsmuth/requirejs-router

इस के रूप में आप प्रत्येक पृष्ठ पर नेविगेट आलसी लोड हो रहा है एएमडी मॉड्यूल के दृष्टिकोण लेता है। बैकबोन राउटर के साथ आपको निर्भरताओं के सामने अपने सभी विचारों की आवश्यकता होती है। यह आपके सभी ऐप्स जावास्क्रिप्ट को पहले पृष्ठ लोड पर लोड करता है। जब आप प्रत्येक मार्ग पर नेविगेट करते हैं तो RequJS राउटर आलसी लोड मॉड्यूल करता है।

उदाहरण मुख्य।जेएस आपके ऐप

define([], function() { 
    'use strict'; 

    // Configure require.js paths and shims 
    require.config({ 
    paths: { 
     'text': 'bower_components/requirejs-text/text', 
     'router': 'bower_components/requirejs-router/router' 
    } 
    }); 

    // Load the router and your layout 
    require(['router', 'js/layout/layoutView'], function(router, LayoutView) { 
    var layoutView = new LayoutView(); 
    // The layout's render method should draw the header, footer, and an empty main-content section 
    // then load the content section. 
    // render: function() { 
    // this.$el.html(this.template({model: this.model})); 
    // router.loadCurrentRoute(); 
    // } 

    // Configure the router 
    router 
     .registerRoutes({ 
     home: {path: '/', moduleId: 'home/homeView'}, 
     order: {path: '/order', moduleId: 'order/orderView'}, 
     notFound: {path: '*', moduleId: 'notFound/notFoundView'} 
     }) 
     .on('statechange', function() { 
     // Render the layout before loading the current route's module 
     layoutView.render.call(layoutView); 
     }) 
     .on('routeload', function(module, routeArguments) { 
     // Attach the content view to the layoutView's main-content section 
     layoutView.$('#main-content').replaceWith(new module(routeArguments).render().el); 
     }) 
     .init({ 
     // We're manually calling loadCurrentRoute() from layoutView.render() 
     loadCurrentRouteOnStateChange: false 
     }); 
); 
); 
संबंधित मुद्दे