2011-10-19 11 views
11

पर डेटा के लिए प्रतीक्षा करें, मुझे लगता है कि मुझे बैकबोन राउटर के उचित उपयोग के पीछे विचार नहीं मिलता है। यहां मुझे यह मिला है:बैकबोन रूटर: पहले

मेरे पास कुछ डेटा है जो पृष्ठ लोड होने पर सर्वर से प्राप्त होता है और फिर इसे मॉडल और संग्रह में पैक करता है। उन मॉडलों और संग्रहों की संख्या अनिश्चित है। मैं राउटर का उपयोग सीधे संग्रह से कुछ संग्रह के दृश्य को प्रस्तुत करने में सक्षम होना चाहता हूं।

समस्या यह है: बैकबोन राउटर जल्दी शुरू होता है, और जब से मैं इसे एक निश्चित दृश्य तक पहुंचने के लिए कहता हूं और render क्रिया को ट्रिगर करता हूं, तो ऐसा नहीं हो सकता है, क्योंकि ये विचार अभी तक नहीं बनाए गए हैं। इसका मतलब है कि लाने के बाद मुझे वास्तव में अपने मार्ग शुरू करना होगा।

अगर यह यह करने के लिए एक उचित तरीका है मैं नहीं जानता, लेकिन केवल विचार मैं के साथ आया है:

  1. लपेटें मार्गों परिभाषा और एक अलग उच्च-स्तरीय में Backbone.history.start(); बिट -एसेसिबल फ़ंक्शन (यानी इसे मैन्युअल रूप से बाद में कॉल करने के लिए तैयार करें)।
  2. भागो कि मेरे संग्रह के fetch()
  3. उन संग्रहों की संख्या के लिए success कॉलबैक के रूप में कार्य अज्ञात है, भी मैं पता लगाने के लिए जब उन सभी को लाए जाने के लिए किया गया है कोई रास्ता नहीं है, और मैं शुरू करने के लिए नहीं करना चाहते हैं एक से अधिक बार मार्ग। तो मैं _.defer() और _.once() का उपयोग करता हूं।

यह काम करता है, लेकिन यह सुनिश्चित बहुत अजीब लग रहा है:

राउटर्स:

window.startRoutes = _.once(function() { 

     var AccountPage = Backbone.Router.extend({ 

      routes: { 
      'set/:id': 'renderSet', 
      }, 

      renderSet: function(setId) { 

       /** … **/ 

       // Call the rendering method on the respective CardView 
       CardsViews[setId].render(); 

      } 

     }); 

     var AccountPageRouter = new AccountPage; 

     Backbone.history.start(); 

    }); 

संग्रह:

window.CardsCollection = Backbone.Collection.extend({ 

    model: Card, 

    initialize: function(params) { 

     /** … **/ 

     // Get the initial data 
     this.fetch({success: function() { 
      _.defer(startRoutes); 
     }}); 

    }, 

}); 

तो मेरे सवाल है ... मैं इसे सही कर रहा हूँ? या ऐसा करने का एक बेहतर तरीका है (होना चाहिए)?

+0

तुरंत अजाक्स कॉल क्यों करें? प्रारंभिक डेटाबेस के लिए आवश्यक जेसन के साथ पृष्ठ को प्रस्तुत क्यों न करें और डेटा को रीढ़ की हड्डी में शुरू करें? – redsquare

उत्तर

14

आप समय से पहले अपने राउटर को परिभाषित कर सकते हैं; यह तब तक कुछ नहीं करेगा जब तक कि आप बैकबोन को कॉल नहीं करते .History.start()।

आप इस तरह इतिहास शुरू करने के लिए अपने संग्रह पर "रीसेट" घटना बाध्य कर सकते हैं:

my_collection.bind("reset", _.once(Backbone.History.start, Backbone.History)) 

फिर रूटर काम करना है जब आपके संग्रह पूरी तरह लोड हो शुरू कर देंगे। मुझे यकीन नहीं है कि यह वही है जो आप खोज रहे हैं (क्योंकि आपने संग्रह की एक चर संख्या का उल्लेख किया है)।

मेरे पास एक समान स्थिति है, सिवाय इसके कि मुझे पहले से पता है कि मैं रूटिंग शुरू करने से पहले कौन से संग्रह लोड करना चाहता हूं।मैं अपने रूटर करने के लिए एक startAfter विधि जोड़ा तो की तरह,: और

window.Workspace = new (Backbone.Router.extend({ 
    . . . 
    startAfter: function(collections) { 
     // Start history when required collections are loaded 
     var start = _.after(collections.length, _.once(function(){ 
     Backbone.history.start() 
     })) 
     _.each(collections, function(collection) { 
     collection.bind('reset', start, Backbone.history) 
     }); 
    } 
    })); 

तो बाद मैं, सेटअप मेरे संग्रह

Workspace.startAfter([collection_a, collection_b, ...]) 

यह स्टैंडअलोन मॉडल के साथ भी काम करने के लिए अनुकूलित किया जा सकता है, हालांकि मैं आपको लगता है 'रीसेट' घटना के अलावा किसी अन्य चीज़ से जुड़ने की ज़रूरत है।

मुझे खुशी है कि मैंने आपका उदाहरण कोड पढ़ा है, _.once और _.defer का उपयोग सही दिशा में मुझे इंगित किया है।

+0

क्या यह 'my_collection.bind (" रीसेट ", _.once (Backbone.history.start) नहीं है? – iblue

+2

आपने '_.once()' के लिए गलत तर्कों का उपयोग किया था। मैं इसे ठीक करने के लिए अपना जवाब संपादित करूंगा। kthxbye :) – iblue

+0

'_.once()' उदाहरण मेरे लिए काम नहीं किया। मुझे इसका उपयोग करना पड़ा: 'app.users.on (" रीसेट ", _.once (फ़ंक्शन() { बैकबोन.history.start(); });' ' –

1

मैं बस अपने .render() विधि में जांच कर रहा हूं कि इसका उपयोग करने से पहले सभी आवश्यक फ़ील्ड भर चुके हैं। अगर यह अभी तक भरा नहीं है - मैं एक 'प्रतिपादन कर रहा हूं ...' विजेट।

और मेरे सभी विचार मॉडल परिवर्तनों के लिए सब्सक्राइब किए गए हैं, this.model.bind('change', this.render, this); द्वारा, इसलिए मॉडल लोड होने के बाद, render() फिर से कॉल किया जाएगा।

संबंधित मुद्दे