JQuery Data () API kullanılarak veri özelliği ayarlanamıyor


131

Bir MVC görünümünde aşağıdaki alana sahibim:

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

Ayrı bir js dosyasında, data-helptextözniteliği bir dize değerine ayarlamak istiyorum . İşte kodum:

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

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

alert()Çağrı bir uyarı iletişim metni "Eski Metin" gösterir, gayet iyi çalışıyor. Ancak, data-helptextözniteliği "Test 123" olarak ayarlama çağrısı çalışmaz. "Eski Metin" hala özniteliğin mevcut değeridir.

Data () çağrısını yanlış mı kullanıyorum? Buna internette baktım ve neyi yanlış yaptığımı göremiyorum.

İşte HTML işaretlemesi:

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

Kod iyi görünüyor. Bu demoda sorun yok . JQuery'nin hangi sürümünü kullanıyorsunuz?
andyb

ASP NET MVC proje şablonu ile birlikte gelen 1.5.1 kullanıyorum. JQuery'yi güncellemem gerekli olabilir mi?
Jason Evans

Tamam, o zaman jQuery'nin sürümü değil. Gerçekten eski bir versiyon olabileceğini düşünüyordum. Kullandığınız data () API v1.2.3'te eklendi
andyb

İşaretlemeyi ekler misiniz lütfen? Özel bir HTML5 data-özelliği mi kullanıyorsunuz ?
andyb

Değeri nasıl gözlemliyorsunuz? jQuery, doğru bir şekilde güncellese de, değeri DOM'a geri götürmez. Bir test ve açıklama için aşağıdaki
cevabıma bakın

Yanıtlar:


239

Belgelerde bahsediliyor.data()

Veri öznitelikleri, veri özelliğine ilk erişildiğinde çekilir ve ardından artık erişilmez veya değiştirilmez (tüm veri değerleri daha sonra dahili olarak jQuery'de depolanır)

Bu ayrıca , jQuery $ .fn.data () 'daki değişiklikler ilgili html 5 data- * özniteliklerini neden güncellemiyor?

Aşağıdaki orijinal cevabımla ilgili demo artık işe yaramıyor gibi görünüyor.

Güncellenen cevap

Yine .data()belgelerden

Katıştırılmış tirelerle özniteliklerin işlenmesi, W3C HTML5 belirtimine uyması için jQuery 1.6'da değiştirildi.

Yani <div data-role="page"></div>aşağıdakiler doğrudur$('div').data('role') === 'page'

$('div').data('data-role')Geçmişte işe yaradığından oldukça eminim ama artık durum böyle görünmüyor. Konsolu açmak zorunda kalmadan HTML'ye günlük kaydeden daha iyi bir vitrin oluşturdum ve çoklu tireden camelCase veri özniteliklerine dönüştürme için ek bir örnek ekledim .

Güncellenmiş demo (2015-07-25)

Ayrıca jQuery Data ve Attr'e bakın.

HTML

<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>

JavaScript (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();

Daha eski demo


Orijinal cevap

Bu HTML için:

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

ve bu JavaScript (jQuery 1.6.2 ile)

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;
});

Demoyu görün

Kullanılması Chrome Geliştirme Araçları Konsolu DOM denetlemek üzere $('#foo').data('helptext', 'Testing 123'); vermez görüldüğü gibi değerini güncellemek Konsolundan ama $('#foo').attr('data-helptext', 'Testing 123');yok.


1
Neyin değiştiğinden emin değilim, ancak keman
gösteriniz

Öyleyse jQuery'nin ikinci bir argüman koymanıza izin vermesinin amacı nedir? Js değişken önbelleğinde depolanan değeri güncellemek için?
ahnbizcad

@gwho Sorunuzu tam olarak anladığımdan emin değilim, ancak 2011'de jQuery 1.6.2 kullanarak orijinal yanıta atıfta bulunduğunuzu varsayıyorum. Eğer öyleyse, o zaman. data('key', 'value')yöntem yapar jQuery önbelleğinde ama performans nedenleriyle (DOM mutasyonu tahmin) DOM kendisi güncelleştirilmezse değerini günceller.
andyb

2
Dolayısıyla, DOM'u güncellemek istiyorsanız .attr('key','value'), yapıp yapmamanıza bakılmaksızın yapmanız gerekir .data('key', 'value'), değil mi? Bu bana gereksiz görünüyor ve önbelleğe alınan DOM'a yazmak isteyeceğiniz, ancak gerçek DOM'a yazmayacağınız bir senaryo hayal etmekte zorlanıyorum. Belki jQuery önbelleğini anlamıyorum; Öyleyse bir ziyaretçi .data(), ekranında değişen her şeyi görür mü yoksa görmez mi?
ahnbizcad

1
Yani bu sadece bir performans meselesi değil; karşılaştırılamazlar. Tamamen farklı amaçları vardır ve DOM'un farklı "sürümlerini" değiştirirler. Öyleyse soruya geri dönelim: ACUTAL DOM'u değiştirmek için .attr () yapmanız gerekiyorsa .data () kullanmanın anlamı nedir? gereksiz görünüyor.
ahnbizcad

34

İle ciddi sorunlar yaşıyordum

.data('property', value);

Bu ayarı değildi data-propertyniteliği.

JQuery kullanılarak başlatıldı .attr():

Eşleşen öğeler kümesindeki ilk öğenin bir özniteliğinin değerini alın veya her eşleşen öğe için bir veya daha fazla öznitelik ayarlayın.

.attr('property', value)

değeri ayarlamak ve

.attr('property')

değeri almak için.

Şimdi sadece çalışıyor!


1
Benim için data özelliğini data () ile değiştirebildim ancak geliştirici araçlarında bu değişikliğin gösterilmediğini fark ettim, bu yüzden attr () ile gittim
drooh

8

@ andyb'nin kabul ettiği yanıtta küçük bir hata var. Yukarıdaki gönderisine yaptığım yoruma ek olarak ...

Bu HTML için:

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

Özniteliğe şu şekilde erişmeniz gerekir:

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

ancak veri yöntemi şöyle:

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

.Data () yöntemi için yukarıdaki düzeltme, "tanımsız" oluşumunu engeller ve veri değeri güncellenir (HTML güncellenmez)

"Veri" özniteliğinin amacı, bir değeri öğeye bağlamak (veya "bağlamak" )tır. onclick="alert('do_something')"Öğeye bir eylemi bağlayan özniteliğe çok benzer ... metin işe yaramaz, yalnızca eylemin öğeyi tıkladığında çalışmasını istersiniz.

Veriler veya eylem öğeye bağlandıktan sonra, genellikle * HTML'yi güncellemeye gerek yoktur, yalnızca verileri veya yöntemi, çünkü uygulamanızın (JavaScript) kullanacağı budur. Performans açısından, neden HTML'yi de güncellemek isteyeceğinizi anlamıyorum, kimse html özelliğini görmüyor (Firebug veya diğer konsollar dışında).

Bunu düşünmek isteyebileceğiniz bir yol: HTML (özniteliklerle birlikte) yalnızca metindir. JavaScript tarafından kullanılan veriler, işlevler, nesneler vb. Ayrı bir düzlemde bulunur. Yalnızca JavaScript'e bunu yapması için talimat verildiğinde, HTML metnini okuyacak veya güncelleyecektir, ancak JavaScript ile oluşturduğunuz tüm veriler ve işlevler, Firebug (veya başka) konsolunuzda gördüğünüz HTML metninden / özelliklerinden tamamen ayrı davranır.

* Vurguluyorum çünkü genellikle HTML'yi korumanız ve dışa aktarmanız gereken bir durumunuz varsa (örneğin, bir tür mikro biçim / veri duyarlı metin düzenleyici) HTML'nin başka bir sayfada yeni yükleneceği bir durum varsa, o zaman belki de güncellenmiş HTML'ye ihtiyacınız vardır. çok.


Teşekkürler. Bu, yanlış örneklerle diğer tüm cevapların yanı sıra yardımcı oldu! dataİçinde attr('data-helptext'kabul edilen cevap ve birçok oylarıyla olanlar çalışmıyor fark yapar. +1
Aleks

6

Bana da aynı şey oldu. Şekline dönüştü

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

size yazılamayan bir nesne verir. Bunu kullanarak çözdüm:

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

Ve o andan itibaren datastandart, yazılabilir bir JS nesnesiydi.


O halde ona nasıl yazarsın?
Bir Yaşam için Works

Üzgünüm Thom, ne demek istiyorsun bilmiyorum ... Yaptıktan sonra $.extend..., istediğin gibi kullanabilirsin data: data.name = 'Nico'; data.questionSolved = true;ve console.log(data)bu yeni eklenen özellikleri gösterecek
Nico

3

Bir alıntı yapmak için:

Veri öznitelikleri, veri özelliğine ilk erişildiğinde çekilir ve artık erişilmez veya değiştirilmez (tüm veri değerleri daha sonra jQuery'de dahili olarak depolanır).

.data() - jQuery Belgeleri

Bu (Açıkçası garip ) sınırlamanın yalnızca kullanımına kapalı olduğuna dikkat edin .data().

Çözüm? .attrBunun yerine kullanın .

Elbette, birçoğunuz onun adanmış yöntemini kullanmamaktan rahatsız olabilir. Aşağıdaki senaryoyu düşünün:

  • "Standart", özel özelliklerin veri kısmına artık gerek kalmayacak / değiştirilecek şekilde güncellenir

Sağduyu - Neden önceden kurulmuş bir özelliği böyle değiştirsinler ? Sadece hayal classolarak değiştirildi başlamak grubuna ve idhiç bir tanımlayıcı . İnternet kırılırdı.

Ve o zaman bile, Javascript'in kendisi bunu düzeltme yeteneğine sahiptir - Ve tabii ki, HTML ile rezil uyumsuzluğuna rağmen, REGEX (Ve çeşitli benzer yöntemler), niteliklerinizi bu yeni efsanevi 'standart'a hızla yeniden adlandırabilir.

TL; DR

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

1

Belirtildiği gibi, .data()yöntem data-özniteliğin değerini gerçekte ayarlamaz ve data-öznitelik değişirse güncellenmiş değerleri okumaz .

Benim çözümüm jQuery'yi .realData()özniteliğin mevcut değerine gerçekten karşılık gelen bir yöntemle genişletmekti :

// 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);

NOT: Elbette kullanabilirsiniz .attr(), ancak benim deneyimlerime göre, çoğu geliştirici (aka ben) görüntüleme .attr()ve .data()birbirinin yerine geçme hatasını yapar ve genellikle birini diğerinin yerine düşünmeden değiştirir. Çoğu zaman işe yarayabilir, ancak özellikle herhangi bir tür dinamik veri bağlamayla uğraşırken hataları ortaya çıkarmanın harika bir yoludur. Bu yüzden kullanarak .realData(), amaçlanan davranış hakkında daha açık olabilirim.


0

Aynı sorunu yaşadım. .Data () yöntemini kullanarak hala veri alabildiğiniz için, yalnızca öğelere yazmanın bir yolunu bulmanız gerekir. Kullandığım yardımcı yöntem bu. Çoğu insanın söylediği gibi, .attr kullanmanız gerekecek. Bunu yaptığını bildiğim gibi herhangi bir _ ile değiştiriyorum. Yerine geçtiği diğer karakterlerden haberdar değilim ... ancak bunu araştırmadım.

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]);
    }
}

DÜZENLEME: 5/1/2017

Yerleşik yöntemleri kullanarak doğru verileri alamadığınız durumlar olduğunu buldum, bu yüzden şimdi kullandığım şey aşağıdaki gibidir:

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;
};
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.