JQuery डेटा () API का उपयोग करके डेटा विशेषता सेट करने में असमर्थ


131

मुझे MVC दृश्य पर निम्न फ़ील्ड मिली है:

@Html.TextBoxFor(model => model.Course.Title, new { data_helptext = "Old Text" })</span>

एक अलग js फ़ाइल में, मैं data-helptextएक स्ट्रिंग मान पर विशेषता सेट करना चाहता हूं । यहाँ मेरा कोड है:

alert($(targetField).data("helptext"));

$(targetField).data("helptext", "Testing 123");

alert()कॉल ठीक काम करता है, यह पाठ 'पुराना पाठ "एक चेतावनी संवाद में पता चलता है। हालांकि, data-helptext"123 परीक्षण" करने के लिए विशेषता सेट करने का कॉल काम नहीं करता है। "पुराना पाठ" अभी भी विशेषता का वर्तमान मूल्य है।

क्या मैं गलत तरीके से डेटा का उपयोग कर रहा हूं? मैंने इसे वेब पर देखा है, और मैं यह नहीं देख सकता कि मैं क्या गलत कर रहा हूं।

यहाँ HTML मार्कअप है:

<input data-helptext="Old Text" id="Course_Title" name="Course.Title" type="text" value="" />

कोड ठीक दिखता है। इस डेमो में कोई समस्या नहीं है । आप किस संस्करण का उपयोग कर रहे हैं?
एंडीब जूल

मैं 1.5.1 का उपयोग कर रहा हूं जो ASP NET MVC प्रोजेक्ट टेम्पलेट के साथ आया था। क्या ऐसा हो सकता है कि मुझे jQuery को अपडेट करने की आवश्यकता है?
जेसन इवांस

ठीक है, यह तब jQuery का संस्करण नहीं है। मैं सोच रहा था कि यह वास्तव में पुराना संस्करण हो सकता है। आपके द्वारा उपयोग किए जा रहे डेटा () API को v1.2.3 में जोड़ा गया है
andyb

क्या आप मार्कअप जोड़ सकते हैं? क्या आप एक कस्टम HTML5 data-विशेषता का उपयोग कर रहे हैं ?
एंडब जूल

आप मूल्य कैसे देख रहे हैं? jQuery डोम पर वापस मूल्य नहीं रखता है, हालांकि यह इसे सही ढंग से अपडेट करता है। एक परीक्षण और स्पष्टीकरण के लिए मेरा जवाब नीचे देखें
andyb

जवाबों:


239

यह प्रलेखन में उल्लिखित है.data()

डेटा-गुण पहली बार डेटा प्रॉपर्टी के एक्सेस होने पर खींचे जाते हैं और फिर एक्सेस नहीं किए जाते हैं या म्यूट किए जाते हैं (सभी डेटा मान तब jQuery में आंतरिक रूप से संग्रहीत होते हैं)

यह भी कवर किया गया था कि jQuery $ .fn.data () से संबंधित HTML 5 डेटा- * विशेषताओं को अपडेट क्यों नहीं किया जाता है?

नीचे मेरे मूल जवाब पर डेमो किसी भी अधिक काम नहीं कर रहा है।

अद्यतन उत्तर

फिर, .data()प्रलेखन से

W3C HTML5 विनिर्देश के अनुरूप एम्बेडेड डैश के साथ विशेषताओं के उपचार को jQuery 1.6 में बदल दिया गया था।

तो <div data-role="page"></div>निम्नलिखित के लिए सच है$('div').data('role') === 'page'

मुझे पूरा यकीन है कि $('div').data('data-role')अतीत में काम किया है, लेकिन ऐसा नहीं लगता कि मामला किसी भी अधिक है। मैंने एक बेहतर शोकेस बनाया है जो कंसोल को खोलने के बजाय HTML में लॉग करता है और डेटा-एट्रिब्यूट रूपांतरण के लिए मल्टी-हाइफ़न का एक अतिरिक्त उदाहरण जोड़ दिया है।

अपडेटेड डेमो (2015-07-25)

इसके अलावा jQuery डेटा बनाम Attr देखें?

एचटीएमएल

<div id="changeMe" data-key="luke" data-another-key="vader"></div>
<a href="#" id="changeData"></a>
<table id="log">
    <tr><th>Setter</th><th>Getter</th><th>Result of calling getter</th><th>Notes</th></tr>
</table>

जावास्क्रिप्ट (jQuery 1.6.2+)

var $changeMe = $('#changeMe');
var $log = $('#log');

var logger;
(logger = function(setter, getter, note) {
    note = note || '';
    eval('$changeMe' + setter);
    var result = eval('$changeMe' + getter);
    $log.append('<tr><td><code>' + setter + '</code></td><td><code>' + getter + '</code></td><td>' + result + '</td><td>' + note + '</td></tr>');
})('', ".data('key')", "Initial value");

$('#changeData').click(function() {
    // set data-key to new value
    logger(".data('key', 'leia')", ".data('key')", "expect leia on jQuery node object but DOM stays as luke");
    // try and set data-key via .attr and get via some methods
    logger(".attr('data-key', 'yoda')", ".data('key')", "expect leia (still) on jQuery object but DOM now yoda");
    logger("", ".attr('key')", "expect undefined (no attr <code>key</code>)");
    logger("", ".attr('data-key')", "expect yoda in DOM and on jQuery object");

    // bonus points
    logger('', ".data('data-key')", "expect undefined (cannot get via this method)");
    logger(".data('anotherKey')", ".data('anotherKey')", "jQuery 1.6+ get multi hyphen <code>data-another-key</code>");
    logger(".data('another-key')", ".data('another-key')", "jQuery < 1.6 get multi hyphen <code>data-another-key</code> (also supported in jQuery 1.6+)");

    return false;
});

$('#changeData').click();

पुराना डेमो


मूल उत्तर

इसके लिए HTML:

<div id="foo" data-helptext="bar"></div>
<a href="#" id="changeData">change data value</a>

और यह जावास्क्रिप्ट (jQuery 1.6.2 के साथ)

console.log($('#foo').data('helptext'));

$('#changeData').click(function() {
    $('#foo').data('helptext', 'Testing 123');
//  $('#foo').attr('data-helptext', 'Testing 123');
    console.log($('#foo').data('data-helptext'));
    return false;
});

डेमो देखें

का उपयोग करना Chrome DevTools कंसोल डोम का निरीक्षण करने, $('#foo').data('helptext', 'Testing 123'); नहीं करता है के रूप में देखा मान अपडेट कंसोल लेकिन $('#foo').attr('data-helptext', 'Testing 123');करता है।


1
निश्चित नहीं है कि क्या बदल गया है, लेकिन आपके
फिडेल

तो फिर jQuery का क्या मतलब है जो आपको दूसरे तर्क में डाल सकता है? जेएस चर कैश में संग्रहीत मूल्य को अपडेट करने के लिए?
एहनबिजद

@ मुझे विश्वास नहीं हो रहा है कि मैं आपके प्रश्न को पूरी तरह से समझ पा रहा हूं, लेकिन मुझे लगता है कि आप 2011 से मूल उत्तर की बात कर रहे हैं jQuery 1.6.2 का उपयोग कर। यदि ऐसा है, तो। data('key', 'value')विधि jQuery कैश में मान को अद्यतन करती है, लेकिन प्रदर्शन कारणों से (मुझे लगता है कि DOM उत्परिवर्तन) DOM स्वयं अपडेट नहीं है।
एंडब जूल

2
इसलिए यदि आप DOM को अपडेट करना चाहते हैं, तो आपको यह करने की आवश्यकता होगी .attr('key','value')कि आपने किया .data('key', 'value')या नहीं, है ना? यह मेरे लिए बेमानी लगता है, और मुझे एक ऐसे परिदृश्य की कल्पना करने में परेशानी हो रही है जहाँ आप कैश्ड डोम को लिखना चाहते हैं, लेकिन असली डोम को नहीं। शायद मैं jQuery के कैश को नहीं समझ पा रहा हूँ; तो क्या कोई आगंतुक उन सभी चीजों को देखेगा जो .data()उनकी स्क्रीन पर संशोधित होती हैं, या नहीं?
अहानिबेकाड

1
तो यह केवल प्रदर्शन की बात नहीं है; उनकी तुलना नहीं की जा सकती। उनके पास पूरी तरह से अलग उद्देश्य हैं, और वे डोम के विभिन्न "संस्करणों" को बदलते हैं। तो इस सवाल पर वापस जाएं: क्या है .data () का उपयोग करने के लिए अगर आपको .attr () को ACUTAL DOM को बदलना है? बेमानी लगता है।
एहनबीकैड

34

मुझे इससे गंभीर समस्या हो रही थी

.data('property', value);

यह data-propertyविशेषता स्थापित नहीं कर रहा था ।

JQuery का उपयोग शुरू किया .attr():

मिलान तत्वों के सेट में पहले तत्व के लिए एक विशेषता का मूल्य प्राप्त करें या प्रत्येक मिलान किए गए तत्व के लिए एक या अधिक गुण सेट करें।

.attr('property', value)

मान सेट करने के लिए और

.attr('property')

मान प्राप्त करने के लिए।

अब यह सिर्फ काम करता है!


1
मेरे लिए मैं डेटा के साथ डेटा प्रॉपर्टी को बदलने में सक्षम था (), लेकिन मैंने डेवलपर टूल में नोटिस किया, यह परिवर्तन नहीं दिखा, इस कारण से मैं attr () के साथ चला गया
drooh

8

@ andyb के स्वीकृत उत्तर में एक छोटा सा बग है। आगे उनकी पोस्ट के ऊपर मेरी टिप्पणी के लिए ...

इसके लिए HTML:

<div id="foo" data-helptext="bar"></div>
<a href="#" id="changeData">change data value</a>

आपको इस तरह की विशेषता का उपयोग करने की आवश्यकता है:

$('#foo').attr('data-helptext', 'Testing 123');

लेकिन इस तरह डेटा विधि:

$('#foo').data('helptext', 'Testing 123');

.Data () विधि के लिए ऊपर दिए गए फिक्स "अपरिभाषित" को रोकेंगे और डेटा मान अपडेट किया जाएगा (HTML पेज)

"डेटा" विशेषता का बिंदु तत्व के साथ एक मान (या "लिंक") को बांधना है। onclick="alert('do_something')"विशेषता के समान , जो तत्व को एक क्रिया को बांधता है ... पाठ बेकार है जब आप तत्व को क्लिक करने के लिए कार्रवाई करना चाहते हैं।

एक बार जब डेटा या एक्शन एलीमेंट से जुड़ा होता है, तो आमतौर पर HTML को अपडेट करने की कोई आवश्यकता नहीं होती है, केवल डेटा या विधि, क्योंकि आपके एप्लिकेशन (जावास्क्रिप्ट) का उपयोग होता है। प्रदर्शन के अनुसार, मैं यह नहीं देखता कि आप HTML को किसी भी तरह से अपडेट क्यों करना चाहते हैं, कोई भी HTML विशेषता नहीं देखता है (फायरबग या अन्य कंसोल को छोड़कर)।

एक तरह से आप इसके बारे में सोचना चाह सकते हैं: HTML (विशेषताओं के साथ) सिर्फ पाठ है। जावास्क्रिप्ट द्वारा उपयोग किए जाने वाले डेटा, फ़ंक्शन, ऑब्जेक्ट आदि एक अलग विमान पर मौजूद हैं। केवल जब जावास्क्रिप्ट को ऐसा करने का निर्देश दिया जाता है, तो यह HTML पाठ को पढ़ेगा या अपडेट करेगा, लेकिन जावास्क्रिप्ट के साथ आपके द्वारा बनाए गए सभी डेटा और कार्यक्षमता HTML पाठ / विशेषताओं से पूरी तरह से अलग हैं जो आप अपने फायरबग (या अन्य) कंसोल में देखते हैं।

* मैं आमतौर पर जोर देता हूं क्योंकि अगर आपके पास एक ऐसा मामला है जहां आपको HTML को संरक्षित और निर्यात करने की आवश्यकता है (जैसे किसी प्रकार का माइक्रो प्रारूप / डेटा अवगत पाठ संपादक) जहां HTML दूसरे पृष्ठ पर ताज़ा लोड होगा, तो शायद आपको HTML अपडेट की आवश्यकता हो भी।


धन्यवाद। इससे गलत उदाहरणों के साथ अन्य सभी उत्तरों में मदद मिली! dataमें attr('data-helptext'अंतर है, जहां स्वीकार किए जाते हैं जवाब और कई वोटों के साथ लोगों को काम नहीं कर रहे बनाता है। +1
हिसू

6

मेरे लिए वही हुआ। परिणाम यह निकला

var data = $("#myObject").data();

आपको एक गैर-लेखन योग्य वस्तु देता है। मैंने इसका उपयोग करके हल किया:

var data = $.extend({}, $("#myObject").data());

और तब से, dataएक मानक, लिखने योग्य जेएस ऑब्जेक्ट था।


फिर आप इसे कैसे लिखते हैं?
एक जीवित

माफ करना थॉम, मुझे नहीं पता कि आपका क्या मतलब है ... करने के बाद $.extend...आप dataजैसा चाहें वैसा उपयोग कर सकते हैं : data.name = 'Nico'; data.questionSolved = true;और console.log(data)इस नए जोड़े गए गुणों को प्रदर्शित करेंगे
निको

3

एक उद्धरण उद्धृत करने के लिए:

पहली बार डेटा प्रॉपर्टी एक्सेस होने पर डेटा- एट्रिब्यूट खींचे जाते हैं और फिर एक्सेस नहीं किए जाते या म्यूट किए जाते हैं (सभी डेटा वैल्यूज़ को तब jQuery में आंतरिक रूप से स्टोर किया जाता है)।

.data() - jQuery प्रलेखन

ध्यान दें कि यह (स्पष्ट रूप से विषम ) सीमा केवल उपयोग के लिए रोक दी गई है .data()

समाधान? .attrइसके बजाय उपयोग करें ।

बेशक, आप में से कई इसे समर्पित पद्धति का उपयोग नहीं करने के साथ असहज महसूस कर सकते हैं। इस परिदृश्य पर विचार करें:

  • 'मानक' को अपडेट किया जाता है ताकि कस्टम विशेषताओं के डेटा-भाग की आवश्यकता न हो या उसे प्रतिस्थापित नहीं किया जा सके

सामान्य ज्ञान - वे पहले से ही स्थापित विशेषता को क्यों बदलेंगे ? जरा कल्पना classकरने के लिए नाम बदला शुरू समूह और idकरने के लिए पहचानकर्ता । इंटरनेट टूट जाएगा।

और फिर भी, जावास्क्रिप्ट में ही इसे ठीक करने की क्षमता है - और निश्चित रूप से, यह HTML के साथ बदनाम असंगतता के बावजूद, REGEX (और इसी तरह के कई तरीके) तेजी से इस नए-पौराणिक 'मानक' के लिए आपकी विशेषताओं का नाम बदल सकता है।

टी एल; डॉ

alert($(targetField).attr("data-helptext"));

1

जैसा कि उल्लेख किया गया है, .data()विधि वास्तव में data-विशेषता के मूल्य को निर्धारित नहीं करेगी , और न ही यह अद्यतन मूल्यों को पढ़ेगी यदि data-विशेषता बदल जाती है।

मेरा समाधान jQuery को एक ऐसी .realData()विधि के साथ विस्तारित करना था जो वास्तव में विशेषता के वर्तमान मूल्य से मेल खाती है:

// Alternative to .data() that updates data- attributes, and reads their current value.
(function($){
  $.fn.realData = function(name,value) {
      if (value === undefined) {
        return $(this).attr('data-'+name);
      } else {
        $(this).attr('data-'+name,value);
      }
  };
})(jQuery);

नोट: निश्चित रूप से आप सिर्फ उपयोग कर सकते हैं .attr(), लेकिन मेरे अनुभव से, अधिकांश डेवलपर्स (उर्फ मुझे) देखने .attr()और .data()विनिमेय होने की गलती करते हैं, और अक्सर बिना सोचे-समझे एक दूसरे के लिए स्थानापन्न कर देते हैं। यह अधिकांश समय काम कर सकता है, लेकिन यह बग को पेश करने का एक शानदार तरीका है, खासकर जब किसी भी प्रकार के गतिशील डेटा बाइंडिंग के साथ काम करना। इसलिए उपयोग करके .realData(), मैं इच्छित व्यवहार के बारे में अधिक स्पष्ट हो सकता हूं।


0

एक ही समस्या थी। चूँकि आप अभी भी .data () पद्धति का उपयोग करके डेटा प्राप्त कर सकते हैं, आपको केवल तत्वों को लिखने का एक तरीका निकालना होगा। यह सहायक विधि है जिसका मैं उपयोग करता हूं। जैसा कि ज्यादातर लोगों ने कहा है, आपको .attr का उपयोग करना होगा। मैं इसे किसी भी _ के साथ बदल रहा हूं - जैसा कि मुझे पता है कि यह ऐसा करता है। मैं किसी भी अन्य पात्रों के बारे में नहीं जानता जो इसे बदलता है ... हालांकि मैंने उस पर शोध नहीं किया है।

function ExtendElementData(element, object){
    //element is what you want to set data on
    //object is a hash/js-object
    var keys = Object.keys(object);
    for (var i = 0; i < keys.length; i++){
        var key = keys[i];
        $(element).attr('data-'+key.replace("_", "-"), object[key]);
    }
}

EDIT: 5/1/2017

मैंने पाया कि अभी भी ऐसे उदाहरण हैं जहां आप तरीकों से निर्मित सही डेटा प्राप्त नहीं कर सकते हैं, इसलिए मैं अब जो उपयोग करता हूं वह इस प्रकार है:

function setDomData(element, object){
    //object is a hash

    var keys = Object.keys(object);
    for (var i = 0; i < keys.length; i++){
        var key = keys[i];
        $(element).attr('data-'+key.replace("_", "-"), object[key]);
    }
};

function getDomData(element, key){
    var domObject = $(element).get(0);
    var attKeys = Object.keys(domObject.attributes);

    var values = null;
    if (key != null){
        values = $(element).attr('data-' + key);
    } else {
        values = {};

        var keys = [];
        for (var i = 0; i < attKeys.length; i++) {
            keys.push(domObject.attributes[attKeys[i]]);
        }

        for (var i = 0; i < keys.length; i++){
            if(!keys[i].match(/data-.*/)){
                values[keys[i]] = $(element).attr(keys[i]);
            }
        }
    }
    return values;
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.