2013-02-14 10 views
14

अभी, जबकि मैं क्रोम देव उपकरण का उपयोग करके रीढ़ की हड्डी या मैरियनेट डिबग कर रहा हूं, मैं ब्रेक पॉइंट्स और व्हाट्नॉट सेट अप करना समाप्त करता हूं, लेकिन एक बार कोड रुक जाता है, यह कहना मुश्किल है कि मैं किस प्रकार की ऑब्जेक्ट्स मैं काम कर रहा हूं क्योंकि क्रोम सब कुछ "बच्चा" लेबल करता है।
(मुझे लगता है कि क्योंकि है कि निर्माता समारोह है)जावास्क्रिप्ट (बैकबोन और मैरियनेट) डिबगिंग

कोई आसान तरीका है या तो इस घोषणा को बदलने या मॉडल/संग्रह किस प्रकार मैं उपयोग कर रहा हूँ निर्धारित करने के लिए है।

राशि इस पागलपन का कारण बनता है मुझ में कुछ इस तरह कर रही शुरू करना चाहता है:

MyModel = Backbone.Model.Extend({ 
    // the $$$ puts it at the top of the inspector, the NAME is just for other devs 
    $$$NAME = "MyModel", 
    ... 
}); 

मैं नहीं वास्तव में इसे पसंद है, क्योंकि इसके ... बदसूरत, इसकी एक चर ... और यह केवल जब मैं चर का निरीक्षण और विस्तार करता हूं तो मदद करता है ... इसे दिखाने के लिए नाम क्रोम उपयोगों को बदलना बहुत अच्छा होगा।

किसी भी मामले में, क्या कोई जानता है कि नाम कैसे बदला जाए? या आपके द्वारा उपयोग किए जाने वाले कुछ अन्य क्लीनर सम्मेलन हैं?

धन्यवाद!

मैट

उत्तर

33

पृष्ठभूमि

यह देखना दिलचस्प है कि ब्राउज़र कंसोल/डीबगर में बैकबोन ऑब्जेक्ट्स के प्रकार को प्रदर्शित करने के लिए "बच्चे" का उपयोग क्यों करता है।

सभी जावास्क्रिप्ट ऑब्जेक्ट्स में एक कन्स्ट्रक्टर प्रॉपर्टी है, जो ऑब्जेक्ट बनाने के लिए प्रयुक्त फ़ंक्शन का संदर्भ है। कंसोल/डीबगर में ऑब्जेक्ट के "प्रकार" को प्रदर्शित करने के लिए ब्राउज़र द्वारा कन्स्ट्रक्टर का उपयोग किया जाता है। कन्स्ट्रक्टर फ़ंक्शन की नाम संपत्ति का मान उपयोग नहीं किया जाएगा यदि यह खाली नहीं है।

function A() { } 
console.log(A.name); // 'A' 

बेनामी कार्यों एक खाली नाम संपत्ति है: हालांकि, केवल कार्यों नामित समारोह भाव एक उपयोगी नाम संपत्ति पाने का उपयोग करके परिभाषित

var B = function() { }; 
console.log(B.name); // '' 

तो, क्या गुमनाम कार्यों के साथ क्या होता है? क्रोम वैरिएबल या प्रॉपर्टी के नाम से अनाम कार्यों का नाम बताता है जिस पर फ़ंक्शन को पहले असाइन किया गया था।यहाँ कुछ उदाहरण हैं:

// 1. named function expression - objects will show as “a” in the console 
function a() { … } 

// 2. anonymous function assigned to variable - objects will show as “b” in the console 
var b = function(){ … }; 

// 3. anonymous function assigned to property of object - objects will show as “container.c” in the debugger 
var container = { 
    c: function() { … } 
}; 

एक अधिक विस्तृत स्क्रिप्ट यहाँ उपलब्ध है: http://jsfiddle.net/danmalcolm/Xa7ma/6/

ब्राउज़र स्रोत कोड से यह नाम प्राप्त करने के लिए प्रकट होता है - वहाँ एक जावास्क्रिप्ट सुविधा है जो आपको कार्यावधि में बता सकते हैं नहीं है पहले चर का नाम जिसे एक फ़ंक्शन सौंपा गया था। अन्य ब्राउज़र एक ऐसे सम्मेलन का समर्थन करते हैं जहां अज्ञात कन्स्ट्रक्टर फ़ंक्शंस पर परिभाषित डिस्प्लेनाम गुण का उपयोग किया जाता है, लेकिन यह वर्तमान में क्रोम में नहीं होता है: http://code.google.com/p/chromium/issues/detail?id=17356

रीढ़ में लौटने के बाद आप एक कस्टम निर्माता (देखें नीचे) उपयोग नहीं कर रहे संभालने, अपने प्रकार एक गुमनाम निर्माता समारोह के साथ खत्म हो जाएगा, Backbone's extend function के रूप में मॉडल, देखें, संग्रह और मार्ग द्वारा प्रयोग किया जाता में बनाए गए इस प्रकार है:

child = function(){ return parent.apply(this, arguments); }; 

यही कारण है कि आप कंसोल/डीबगर में अपनी बैकबोन ऑब्जेक्ट्स के बगल में "बच्चा" देखते हैं। यह आपके ऑब्जेक्ट के कन्स्ट्रक्टर के लिए उपयुक्त नाम पर ब्राउजर का सबसे अच्छा अनुमान है।

समाधान

अपने वस्तुओं के लिए एक बेहतर प्रकार का नाम है जब आप अपने रीढ़ प्रकार को परिभाषित आप पहली बार "protoProps" तर्क माध्यम से एक नामित निर्माता की आपूर्ति कर सकते देने के लिए,। इस प्रकार बस एक निर्माता संपत्ति है कि "जनक" निर्माता के लिए एक कॉल लपेटता जोड़ें:

var Product = Backbone.Model.extend({ 
    constructor: function Product() { 
     Backbone.Model.prototype.constructor.apply(this, arguments); 
    } 
}); 

अपने उत्पाद मॉडल उदाहरणों अब डीबगर में दिखेगा वास्तव में अच्छा।

यह आपके द्वारा परिभाषित प्रत्येक दृश्य, मॉडल, संग्रह और मार्ग के लिए ऐसा करने के लिए थोड़ा बोझिल है। आप बंदर पैच बैकबोन का विस्तार कार्य आपके लिए काम करने के लिए कर सकते हैं।

आपको सबसे पहले अपने प्रकार के नाम परिभाषित करने के लिए एक सम्मेलन स्थापित करने की आवश्यकता है।

var Product = Backbone.Model.extend({ 
    __name__: 'Product' 
    // other props 
}); 

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

(function() { 

    function createNamedConstructor(name, constructor) { 

     var fn = new Function('constructor', 'return function ' + name + '()\n' 
      + '{\n' 
      + ' // wrapper function created dynamically for "' + name + '" constructor to allow instances to be identified in the debugger\n' 
      + ' constructor.apply(this, arguments);\n' 
      + '};'); 
     return fn(constructor); 
    } 

    var originalExtend = Backbone.View.extend; // Model, Collection, Router and View shared the same extend function 
    var nameProp = '__name__'; 
    var newExtend = function (protoProps, classProps) { 
     if (protoProps && protoProps.hasOwnProperty(nameProp)) { 
      // TODO - check that name is a valid identifier 
      var name = protoProps[nameProp]; 
      // wrap constructor from protoProps if supplied or 'this' (the function we are extending) 
      var constructor = protoProps.hasOwnProperty('constructor') ? protoProps.constructor : this; 
      protoProps = _.extend(protoProps, { 
       constructor: createNamedConstructor(name, constructor) 
      }); 
     } 
     return originalExtend.call(this, protoProps, classProps); 
    }; 

    Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = newExtend; 
})(); 
+3

वाह, इसे डिफ़ॉल्ट रूप से रीढ़ की हड्डी में शामिल किया जाना चाहिए ....एक लाख दान धन्यवाद, यह बहुत अच्छा है। – MattyP

4

हां। नामांकित फ़ंक्शन अभिव्यक्ति का उपयोग करके आप मॉडल/संग्रह/constructor पर ओवरराइड करके कंसोल डिस्प्ले नाम बदल सकते हैं। यह भी सांत्वना उत्पादन को नियंत्रित करने के toString ओवरराइड करने के लिए helpul जब मॉडल कहते हैं, के साथ स्ट्रिंग प्रकार के लिए मजबूर किया जाता है हो सकता है, + ऑपरेटर:

var model = new Model({id:1,foo:"bar"}) 

console.log("state: " + model); 
console.log(model); 

आप मिल जाएगा:

App.Model = Backbone.Model.extend({ 

    //define constructor using a named function expression 
    constructor: function Model() { 
    Backbone.Model.prototype.constructor.apply(this, arguments); 
    }, 

    //override toString to return something more meaningful 
    toString: function() { 
    return "Model(" + JSON.stringify(this.attributes) + ")"; 
    } 
}); 
साथ

तो :

state: Model({"id":1,"foo":"bar"}) 
► Model 
+0

अच्छा! पता नहीं था कि हम ऐसा कर सकते हैं :) ... भी, हम मैरियनेट के लिए स्रोत प्रतीकों पर काम कर रहे हैं। मैं v1.0 रिलीज के लिए यह उम्मीद कर रहा हूँ। यह डिबगिंग में बहुत मदद करनी चाहिए। –

+0

@DerickBailey, स्रोत मानचित्र अद्भुत होंगे। मैरियनेट पर आपका काम बैकबोन कोर में कुछ भी योगदान दे सकता है? https://github.com/documentcloud/backbone/issues/2143 – jevakallio

2

डिबगिंग के लिए इस library इस extension का उपयोग करने पर विचार।

2

इसके अलावा अपने आवेदन के शीर्ष पर

"use strict" 

जोड़ने का प्रयास करें। Backbone.marionette.js की लाइन 1 पर अपरिभाषित जैसे स्टैक ट्रेस त्रुटियों को देने के बजाय यह इंस्टेंस आउटपुट करेगा और अधिक दृश्यमान जानकारी होगी जैसे HistoryView नहीं मिला था।

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