2013-04-19 5 views
11

के साथ एक वस्तु से संबद्ध नहीं करते करने के लिए मैं अपने जे एस सेटअप में एक मास्टर वस्तु है, यानी .:कैसे एक डोम तत्व

var myGarage = { 
    cars: [ 
     { 
      make: "Ford", 
      model: "Escape", 
      color: "Green", 
      inuse: false 
     }, 
     { 
      make: "Dodge", 
      model: "Viper" 
      color: "Red", 
      inuse: true 
     }, 
     { 
      make: "Toyota", 
      model: "Camry" 
      color: "Blue", 
      inuse: false 
     } 
    ] 
} 

अब मैं अपने कारों पाश और उन्हें किसी तालिका में डाल दिया। तालिका में मेरे पास एक बटन भी है जो मुझे कार को "उपयोग में" और "उपयोग में नहीं" के रूप में टॉगल करने देता है।

मैं अपनी पंक्ति के साथ प्रत्येक पंक्ति के डोम एलिमेंट को कैसे जोड़ सकता हूं, ताकि अगर मैं "इनयूज" ध्वज टॉगल करूँ, तो मैं मास्टर ऑब्जेक्ट को अपडेट कर सकता हूं?

+0

क्या आपने jQuery की '.ata()' विधि पर विचार किया था? – Barmar

+0

मैंने किया, लेकिन मैं प्रत्येक कार ऑब्जेक्ट के अंदर संदर्भ कैसे संग्रहीत करूं? – Steve

+0

कुछ $ '(" ") .डेटा (कार) .appendTo (तालिका)' – Barmar

उत्तर

7

मैं addEventListener पर विचार करने का सुझाव दूंगा, और एक निर्माता जो आपके ऑब्जेक्ट को eventListener इंटरफ़ेस पर अनुरूप करता है।

इस तरह आप अपने ऑब्जेक्ट, अपने तत्व और उसके हैंडलर के बीच एक अच्छा सहयोग कर सकते हैं।

ऐसा करने के लिए, एक कन्स्ट्रक्टर बनाएं जो आपके डेटा के लिए विशिष्ट है।

function Car(props) { 
    this.make = props.make; 
    this.model = props.model; 
    // and so on... 

    this.element = document.createElement("div"); // or whatever 

    document.body.appendChild(this.element);  // or whatever 

    this.element.addEventListener("click", this, false); 
} 

फिर इंटरफ़ेस को लागू:

Car.prototype.handleEvent = function(e) { 
    switch (e.type) { 
     case "click": this.click(e); 
     // add other event types if needed 
    } 
} 

फिर प्रोटोटाइप पर अपने .click() हैंडलर को लागू।

Car.prototype.click = function(e) { 
    // do something with this.element... 
    this.element.style.color = "#F00"; 

    // ...and the other properties 
    this.inuse = !this.inuse 
} 

तो फिर तुम सिर्फ सरणी से अधिक पाश, और प्रत्येक आइटम के लिए एक नया Car वस्तु बना सकते हैं, और यह नए तत्व बना सकते हैं और श्रोता (रों) जोड़ देंगे।

myGarage.cars.forEach(function(obj) { 
    new Car(obj) 
}) 
+0

उन्होंने कहा कि वह jQuery का उपयोग कर रहा है, इसलिए उनमें से प्रत्येक को एक-लाइनर के लिए संक्षिप्त किया जा सकता है। – Barmar

+0

विस्तृत स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। मैं वास्तव में इसे बहुत समान कर रहा हूं। उपर्युक्त विवरण मेरी वास्तविक समस्या को स्थापित करने के लिए केवल एक छोटा सा स्पष्टीकरण था: मैं 'tr' rowElement के अंदर प्रत्येक कार ऑब्जेक्ट (myGarage ऑब्जेक्ट के भीतर) का संदर्भ कैसे संग्रहीत करूं, ताकि मैं आसानी से मूल ऑब्जेक्ट को एक क्लिक के अंदर अपडेट कर सकूं हैंडलर। – Steve

+0

@ बाड़ार: शायद मुझे यह याद आ रही है, लेकिन मुझे नहीं लगता कि यह कहां है "jQuery का उपयोग कर"। मुझे टैग दिखाई देता है, लेकिन यह है। –

0

आप अपनी जानकारी में कुछ प्रकार की आईडी या विशिष्ट पंक्ति चाहते हैं, अन्यथा आपको इसे करने के लिए सरणी अनुक्रमणिका पर भरोसा करना होगा। किसी भी तरह से आप data attributes का उपयोग कर डेटा स्टोर करना चाहते हैं।

तो जब आप पाश के माध्यम से:

for (var i = 0, l = array.length; i < l; i++) { 
    var div = '<tr data-car="' + JSON.stringify(array[i]) + '" data-index="' + i + '"><td></td></tr>' 
} 

और अपने क्लिक करें घटना पर:

$('button').click(function() { 
    var carIndex = $(this).closest('tr').attr('data-index'); 
    var carData = $(this).closest('tr').attr('data-car'); 
    if (carData) carData = JSON.parse(carData); 

    myGarage.cars[carIndex].inUse = true; 
}) 

आप डोम के लिए डेटा के लिए बाध्य हैं, तो आप भी वास्तविक जे एस डेटा अद्यतन करने की आवश्यकता नहीं हो सकता है । तालिका में प्रत्येक पंक्ति पर जा सकते हैं और उस डेटा-ऑब्जेक्ट को फिर से बना सकते हैं जिससे आपने तालिका बनाई थी।

+0

इस दृष्टिकोण के साथ समस्या यह है कि मैं 'डेटा-विशेषता' में प्रत्येक कार की ऑब्जेक्ट की प्रतिलिपि संग्रहीत करता हूं। यही वह नहीं है जो मैं चाहता हूं। मैं मास्टर ऑब्जेक्ट में मूल ऑब्जेक्ट का संदर्भ चाहता हूं। – Steve

+0

तो डेटा-विशेषताओं का उपयोग करके केवल इंडेक्स को स्टोर करें? डीओएम तत्व का संदर्भ प्राप्त करने का कोई निश्चित तरीका नहीं है। यदि आप इसे jQuery के साथ ढूंढना चाहते हैं और इसे अपनी कार की ऑब्जेक्ट में सहेजना चाहते हैं, तो jQuery संदर्भ विश्वसनीय रूप से सेट नहीं रहेगा। आप अपने मुख्य myGarage ऑब्जेक्ट में कच्चे तालिका तत्व (उदाहरण के लिए document.getElementById) को स्टोर करने में सक्षम हो सकते हैं, हालांकि आपको फंक्शन कॉल के बीच संदर्भ रहता है। –

+0

हम कार इंडेक्स को पंक्ति में क्यों जोड़ रहे हैं .. इसे बटन पर क्यों न जोड़ें। यह निकटतम पंक्ति खोजने के लिए मुझे एक डोम क्वेरी बचाएगा। मेरा जवाब वही करता है। अगर इसके लिए कोई कारण है तो मुझे बताएं। – sachinjain024

14

आप वास्तव में एक नोड के लिए सीधे एक वस्तु संलग्न कर सकते हैं:

var n = document.getElementById('green-ford-escape'); 
n.carObject = myGarage.cars[0]; 
n.onclick = function() { 
    doSomethingWith(this.carObject); 
} 

अस्पष्टता को दूर करने, कुछ मामलों में की इसी के लिए, यह और अधिक स्पष्ट n बजाय this का उल्लेख करने के ऊपर ईवेंट हैंडलर लिखना है:

n.onclick = function() { 
    doSomethingWith(n.carObject); 
} 

तुम भी जुड़ी घटना से वस्तु को सीधे उल्लेख कर सकते हैं:

var n = document.getElementById('green-ford-escape'); 
n.onclick = function() { 
    doSomethingWith(myGarage.cars[0]); 
} 

बाद के मामले में, myGarage वैश्विक होना चाहिए। आप इस करते हैं और इसे सही ढंग से काम करने की उम्मीद कर सकते हैं:

(function(){ 

    var myGarage = { /* ... etc ... */ }; 

    var n = document.getElementById('green-ford-escape'); 
    n.onclick = function() { 
     doSomethingWith(myGarage.cars[0]); 
    } 

})(); 

नोड के समारोह समारोह सही ढंग से स्थानीय चर "पर पकड़" होगा, प्रभावी रूप से एक निजी वैरिएबल बनाने।

आप अपने क्रोम/एफएफ/आईई कंसोल में इस परीक्षण कर सकते हैं:

var o = {a: 1}; 
var n = document.createElement('div'); 
n.innerHTML = "click me"; 
n.data = o; 
n.onclick = function() { n.data.a++; console.log(n.data, o); } 
document.body.appendChild(n); 

आप a मान बढ़ाने के साथ सांत्वना लॉग प्रत्येक क्लिक के साथ दो समान वस्तुओं, प्रत्येक देखना चाहिए।

से सावधान रहें जो n.data को एक आदिम पर सेट करने से संदर्भ नहीं बनाया जाएगा। यह मूल्य की प्रतिलिपि बनायेगा।

+0

मीठे ... यही वह है जिसे मैं ढूंढ रहा था। तो डोमेलेमेंट से जुड़ी नेस्टेड ऑब्जेक्ट का संदर्भ स्टोर करना पूरी तरह ठीक है? – Steve

+0

@Steve मैंने हाल ही में चश्मे की जांच नहीं की है। और मुझे संदेह है कि इवेंट हैंडलर में ऑब्जेक्ट का जिक्र कुछ लोगों के दिमाग में कम "खतरनाक" है। लेकिन, ऑब्जेक्ट को नोड पर सीधे संलग्न करना * काम करेगा *। बस बिल्टिन विशेषताओं के साथ टकराव के लिए देखें - मुझे लगता है कि spec 'x-vendorname-'या' data-' के साथ सभी कस्टम विशेषताओं को उपसर्ग करने का सुझाव देता है। ('x-विक्रेता 'उपयोगकर्ता एजेंटों के लिए सिफारिश हो सकती है।) – svidgen

+0

ध्यान रखें कि डीओएम ऑब्जेक्ट्स को विस्तारित करना इस तरह से सुरक्षित वातावरण में केवल सुरक्षित है। कंगैक्स द्वारा यहां एक महान लेख दिया गया है: http: // perfectionkills।कॉम/व्हाट्स-गलत-विस्तार-द-डोम/# lack_of_specification। – tomekwi

0

आप यह जानने के लिए एचटीएमएल 5 डेटा- * विशेषता का उपयोग कर सकते हैं। आप इस

var table = $('<table>'); // Let's create a new table even if we have an empty table in our DOM. Simple reason: we will achieve single DOM operation (Faster) 

for (var i=0; i<myGarbage.cars.length; i++) { 
    // Create a new row and append to table 
    var tr = $('<tr>').appendTo(table); 

    var carObject = myGarbage.cars[i]; 
    // Traverse the JSON object for each car 
    for (var key in carObject) { 
     // Create other cells. I am doing the last one 
     var td = $('<td>').appendTo(tr); 
     var button = $('<button>').attr('data-carId', i).addClass('toggle-inuse').appendTo(td); 
    } 
} 
// If en ampty table awaits me in DOM 
$('#tableId').html(table.html()); 

की तरह कुछ करना ही होगा अब हम बटन पर घटना श्रोता जोड़ना होगा: -

$('.toggle-inuse').click(function() { 
    var i = $(this).data('carId'); 
    myGarbage.cars[i].inuse = !myGarbage.cars[i].inuse; //Wow done 
} 

इस बाहर की कोशिश करो !!

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