2012-05-01 14 views
17

मैं अपने मॉडल पर कस्टम कन्स्ट्रक्टर बनाने के लिए कुछ उदाहरण ढूंढ रहा हूं। मैं संरचना को मॉडल/डेटा को अलग-अलग करना चाहता हूं, फिर इसे केवल गुणों के रूप में सेट करना चाहता हूं।Backbone.js कस्टम कन्स्ट्रक्टर?

क्या कोई मुझे ऐसा करने का कुछ बुनियादी उदाहरण दिखा सकता है?

धन्यवाद!

+1

आप 'parse' (http://documentcloud.github.com/backbone/#Model-parse) का उपयोग कर आवश्यकतानुसार सर्वर के JSON को बदल सकते हैं। शायद आपको यह स्पष्ट करना चाहिए कि आप क्या करने की कोशिश कर रहे हैं, एक उदाहरण मदद कर सकता है। –

उत्तर

39

तुम सच में निर्माता ओवरराइड करने के लिए चाहते हैं, Backbone.Model.extend() करने के लिए एक constructor संपत्ति गुजरती हैं, उदाहरण के लिए:: ओवरराइड initialize विधि सही तरीका है

var Klass = Backbone.Model.extend({ 

    constructor : function (attributes, options) { 

    // ... 

    } 

}); 

आप में निर्मित निर्माता कॉल करने के लिए चाहते हैं अपने कस्टम कन्स्ट्रक्टर से, आप कुछ ऐसा कर सकते हैं:

var Klass = Backbone.Model.extend({ 

    constructor : function (attributes, options) { 

    Backbone.Model.apply(this, arguments); 

    } 

}); 

या यदि आप वीए का नाम दोहराना नहीं चाहते हैं riable सभी उप वर्ग से अधिक माता पिता क्लास वाली, या आपको लगता है कि चर बदलते के मूल्य के बारे में चिंता नहीं करना चाहते, तो आप निम्न की तरह कुछ कर सकते हैं:

var Klass; 

var parent_klass = Backbone.Model.prototype; 

(function (parent_klass) { 

    Klass = parent_klass.constructor.extend({ 

    constructor : function (attributes, options) { 

     parent_klass.constructor.apply(this, arguments); 

    } 

    }); 

})(parent_klass); 

या आप जिस तरह से @Claude suggests पसंद करते हैं, लेकिन माता-पिता वर्ग वर नाम के बजाय उप वर्ग के भीतर उप वर्ग चर नाम दोहरा:

var Klass = Backbone.Model.extend(

    { 

    constructor : function (attributes, options) { 

     Klass.parent_klass.constructor.apply(this, arguments); 

    } 

    }, 

    { 

    parent_klass : Backbone.Model.prototype 

    } 

); 

आपको उससे अधिक की सलाह चाहते हैं, तो आप आप क्या हासिल करना चाहते हैं के बारे में अधिक विशिष्ट होना होगा।

अंतर्निहित कन्स्ट्रक्टर कार्यक्षमता के बाद आप जो भी करना चाहते हैं, आपको शायद initialize() में करना चाहिए।

Backbone.Model = (function(Model) { 
    // Define the new constructor 
    Backbone.Model = function(attributes, options) { 
    // Your constructor logic here 
    // ... 
    // Call the default constructor if you wish 
    Model.apply(this, arguments); 
    // Add some callbacks 
    this.on('event', this.myCallback, this); 
    }; 
    // Clone static properties 
    _.extend(Backbone.Model, Model);  
    // Clone prototype 
    Backbone.Model.prototype = (function(Prototype) { 
    Prototype.prototype = Model.prototype; 
    return new Prototype; 
    })(function() {}); 
    // Update constructor in prototype 
    Backbone.Model.prototype.constructor = Backbone.Model; 
    return Backbone.Model; 
})(Backbone.Model); 

उसके बाद क्या आप वाकई Backbone.Collection प्रोटोटाइप अद्यतन Backbone.Model निर्माता का उपयोग करता है बनाने के लिए है:

_.extend(Backbone.Collection.prototype, { 
    model: Backbone.Model 
}); 

+1

'this' के साथ संयोजन में __super__ का उपयोग करने में सावधान रहें। 'यह' हमेशा बनाई गई ऑब्जेक्ट को इंगित करेगा, जिससे अनंत लूप हो जाएगा। अधिक जानकारी के लिए मेरा जवाब देखें। – Claude

+0

@ क्लाउड हां, इसका उल्लेख करने के लिए धन्यवाद। मेरा जवाब फिर से अपडेट करने का अर्थ रहा है: वह। मैंने इस उत्तर को पोस्ट करने के बाद '__super__' का उपयोग करना बंद कर दिया है। – JMM

+0

प्रोटोटाइप का उपयोग कर मॉडल के हर उदाहरण के लिए एक कन्स्ट्रक्टर बनाने के बारे में कैसे? बैकबोन.मोडेल का एक उदाहरण बनाते समय मैं कन्स्ट्रक्टर विधि को संशोधित करने का प्रयास कर रहा हूं। मैं नोड के सॉकेट.ओ फ्रेमवर्क के साथ कुछ ऑटो बाध्यकारी काम करना चाहता हूं। BuT मैं अपने द्वारा बनाए गए प्रत्येक मॉडल के लिए एक कन्स्ट्रक्टर विधि संलग्न नहीं करना चाहता हूं। प्रारंभिक कार्यों का प्रोटोटाइप जोड़ना; एकमात्र मुद्दा यह है कि अगर मॉडल के साथ एक पारित किया जाता है तो यह अंडरस्कोर विस्तार विधि के माध्यम से इसे ओवरराइड करता है। – kr1zmo

0

ऐसा लगता है कि आप initialize विधि की तलाश में हैं। जब आप एक नया मॉडल बनाने यह कहा जाता है, और अगर जो कुछ के लिए आप के लिए इसकी आवश्यकता आप का उपयोग कर सकते हैं:

var myModel = Backbone.Model.extend({ 
    initialize: function() { 
    // do something besides setting attributes or model 
    alert('myModel is ready for action!'); 
    } 
}); 

new myModel(); 

आप और अधिक शामिल कुछ करने के लिए देख रहे हैं, तो आप रीढ़ कोर में constructor विधि ओवरराइड हो सकता है। हालांकि, यह एक बहुत ही कठिन व्यवसाय है। यदि आप कर सकते हैं तो उजागर तरीकों के साथ काम करना बेहतर होगा!

+1

मैं एक कस्टम निर्माता की तलाश में हूं। मैं मॉडल पर बस सेट करने के लिए भेजे गए गुण नहीं चाहता हूं। मैं कन्स्ट्रक्टर को ओवरराइड करना चाहता हूं। – fancy

+1

आप निश्चित रूप से एक विकल्प हैश को 'प्रारंभिक' करने के लिए पास कर सकते हैं, इसे फ़ंक्शन के भीतर कुशल बना सकते हैं, और वहां से जो भी विशेषताओं की आवश्यकता है उसे सेट कर सकते हैं। – rjz

+0

'कन्स्ट्रक्टर' "खुलासा" है, और दस्तावेज़ बताते हैं कि आप इसे कैसे ओवरराइड कर सकते हैं। 'प्रारंभिक' एक अलग उद्देश्य प्रदान करता है। – Madbreaks

2

से आप अपने मॉडल लिखने के लिए चाहते हैं, तो इस तरह:

var YourModel = function() { 
    // your constructor here 
}; 

_.extend(YourModel.prototype, Backbone.Model.prototype, { 
    // your model method here 
}); 

सावधान रहो, मैं तुम्हें Backbone.Model निर्माता source code से परामर्श करने की जरूरत है। लेकिन मुझे लगता है कि यह एक अच्छा विचार नहीं है।

var YourModel = Backbone.Model.extend({ 
    initialize: function (attrs, options) { 
     Backbone.Model.prototype.initialize.apply(this, arguments); // call super constructor 

     // your constructor code here 
    } 
}); 
+0

'Backbone.Model' प्रारंभिक विधि खाली है, सुनिश्चित नहीं है कि इसे कॉल करने में कोई बिंदु है या नहीं। – raine

+0

@rane क्या आप वाकई भविष्य में रिलीज के मामले में होंगे? सुपर विधि को कॉल करने के लिए निश्चित रूप से बुद्धिमान। – Madbreaks

6

यह कैसे मैं डिफ़ॉल्ट Backbone.Model निर्माता ओवरराइड है मेरी राय में इस दृष्टिकोण का 'लाभ' यह है कि आप बैकबोन.मोडेल का उपयोग अपने मॉडल कन्स्ट्रक्टर के रूप में कर सकते हैं, जिससे परिवर्तन अधिक पारदर्शी हो जाता है।

+1

+1 मेरे मॉडल को कुछ और नहीं बढ़ाने के लिए +1 – blockhead

7

जैसा कि मैंने टिप्पणी में उल्लेख किया है, this.constructor.__super__ (या this.__super__) का उपयोग करते समय सावधानी बरतें, ताकि आप अंतहीन पाश (Maximum call stack size exceeded क्रोम में) समाप्त हो जाएं।

कंसोल में निम्नलिखित का प्रयास करें (अपने जोखिम पर है, यह आगे उल्लिखित अंतहीन लूप को बढ़ावा मिलेगा)

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    this.constructor.__super__.constructor.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    this.constructor.__super__.constructor.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// (8192) log: A 
// > RangeError: Maximum call stack size exceeded 

कारण यह है कि जब B की आवृत्ति A अंक के लिए निर्माता में B, this बनाने , इसलिए this.constructor.__super__.constructorA के निर्माता की ओर इशारा करता रहता है, जिसे समय और समय कहा जाता है।

आप "इच्छित व्यवहार", निम्नलिखित वाक्यविन्यास से एक का उपयोग करना चाहते हैं: __super__ बिना

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    A.__super__.constructor.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    B.__super__.constructor.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// log: A 
// > A.extend.constructor 

या सीधे:

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    Backbone.Model.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    A.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// log: A 
// > A.extend.constructor 
-1

कुछ जब Backbone.Model निर्माता अधिभावी के बारे में पता होना करने के लिए - यदि आप Backbone.Model.apply पर कॉल नहीं करते हैं तो Model.cid सेट नहीं किया जा सकता है।

यह बुरा है - यदि एकाधिक मॉडलों में सीआईडी ​​सेट नहीं है, तो संग्रह आपके संग्रह में पहले मॉडल का डुप्लिकेट मान सकता है - और इसे जोड़ने की अनुमति नहीं देगा।