JSON nesnesini HTML jQuery'deki veri özniteliğinde depolayın


134

Bu data-yaklaşımı kullanarak verileri bir HTML etiketinde şu şekilde depoluyorum :

<td><"button class='delete' data-imagename='"+results[i].name+"'>Delete"</button></td>

Daha sonra verileri şöyle bir geri aramada alıyorum:

$(this).data('imagename');

Bu iyi çalışıyor. Takılıp kaldığım şey, nesnenin özelliklerinden sadece biri yerine nesneyi kurtarmaya çalışmak. Bunu yapmaya çalıştım:

<td><button class='delete' data-image='"+results[i]+"'>Delete</button></td>

Sonra name özelliğine şu şekilde erişmeye çalıştım:

var imageObj = $(this).data('image');
console.log('Image name: '+imageObj.name);

Günlük bana söylüyor undefined. Öyleyse data-özniteliklerde basit dizeleri depolayabilirim ama JSON nesnelerini saklayamıyorum ...

Bu sözdizimi çocuğunu da şanssız kullanmayı denedim:

<div data-foobar='{"foo":"bar"}'></div>

data-Yaklaşımı kullanarak gerçek bir nesnenin HTML etiketinde nasıl saklanacağına dair bir fikriniz var mı?

Yanıtlar:


139

metne gömmek yerine sadece şunu kullanın: $('#myElement').data('key',jsonObject);

aslında html'de depolanmaz, ancak jquery.data kullanıyorsanız, bunların hepsi yine de soyutlanmıştır.

JSON'u geri almak için ayrıştırmayın , şunu arayın:

var getBackMyJSON = $('#myElement').data('key');

Eğer alıyorsanız [Object Object]yerine direkt JSON, sadece veri tuşu ederek JSON erişmek:

var getBackMyJSON = $('#myElement').data('key').key;

1
Bu nedenle, veri yaklaşımını kullanmak, yukarıda gösterdiğim gibi hmtl etiketini koyarak tablodaki her sil düğmesinin değerini kaydetmeme olanak tanır (her düğme farklı bir json nesnesi alır ...). Önerdiğiniz şey, her nesneyi karşılık gelen sil düğmesiyle ilişkilendirmeme izin verecek mi? Bunu nasıl yapardım, nasıl kullanırım $ ('# myElement'). aynı şekilde? Üzgünüm, bu konuda tecrübeli değilim. Teşekkürler
zumzum

Böylece her html düğmesine bir dizin atadım: <td> <button class = 'delete' data-index = '"+ i +"'> Sil </button> </td> ve JSON nesnelerinden oluşan bir dizi depoladım $ nesneler değişkeninde. Sonra bir butona tıklandığında buton indeksine şu şekilde bakarım: var buttonIndex = $ (this) .data ('index'); ve sonra önceden kaydedilmiş olan ilgili nesneyi şu şekilde alıyorum: $ objects [buttonIndex]. Bu iyi çalışıyor, bunu yapmanın doğru yolu olup olmadığından emin değilim. Geri bildiriminiz için teşekkürler!
zumzum

Alan, PHP kodlamasından JSON'u içeriyorsa, bunun yerine bunu yapmak isteyebilirsiniz: htmlspecialchars(json_encode($e))( Nicolas'ın fikirlerine cevap yorumları).
CPHPython

ilk örnekte, jsonObjectsertleştirilmesi gerekiyor mu? düzenleme: başkasına yardımcı olması durumunda, bu sorunun cevabını burada buldum: stackoverflow.com/a/42864472 "You don't need to stringify objects to store them using jQuery.data()"
user1063287

154

Aslında, son örneğiniz:

<div data-foobar='{"foo":"bar"}'></div>

iyi çalışıyor gibi görünüyor (bkz. http://jsfiddle.net/GlauberRocha/Q6kKU/ ).

Güzel olan şey, data-özniteliğindeki dizenin otomatik olarak bir JavaScript nesnesine dönüştürülmesidir. Aksine, bu yaklaşımda herhangi bir sakınca görmüyorum! Nesne özellikleri aracılığıyla JavaScript'te kullanıma hazır bir veri kümesinin tamamını depolamak için tek bir özellik yeterlidir.

(Not: veri özniteliklerine otomatik olarak String yerine Object türü verilmesi için, özellikle anahtar adlarını çift tırnak içine almak için geçerli JSON yazmaya dikkat etmelisiniz).


20
O kimseyi yardımcı olur, İşte yukarıda erişmek için: $('div').data('foobar').foo. api.jquery.com/data
Gary

5
@GlauberRocha, Ya veriler tek alıntı içeriyorsa? php'den 'iken benim için çalışmıyor echo json_encode($array). Öznitelik değerini tek tırnak ile sonlandıracağından. Diziden manuel olarak tek tırnaktan kaçış dışında herhangi bir öneri.
Ravi Dhoriya ツ

1
@ Log1c ツ Sadece bir fikir: 'as &amp;quot;(çift çıkış karakterli HTML varlığı) olarak kodlamayı deneyin, böylece kaynağınızda & quot; olarak görüntülenir. Ama belki de "tek alıntıdan elle kaçmak" derken kaçınmak isteyeceğiniz türden bir şey ...
Nicolas Le Thierry d'Ennequin

2
@GlauberRocha cevap için teşekkürler. Ben de aynı numarayı kullanarak çözdüm. Htmlspecialchars () [ php.net/manual/en/function.htmlspecialchars.php] kullandım . Çözüldü. :)
Ravi Dhoriya ツ

1
Nesne özelliklerinden biri tek bir alıntı içeren bir dize olduğunda bu yöntemi kullanırken sorunla karşılaştım. Veri özniteliği karşılaşılan ilk tek tırnakta biter ve geçerli JSON olmadığı için bir dize olarak yorumlanır. Dizeyi kodlamak mümkün olabilir, ancak en kolay çözümün birden çok veri özniteliği kullanmak olduğunu buldum.
Jon Hulka

43

Benim için böyle çalıştı.

Nesne

var my_object ={"Super Hero":["Iron Man", "Super Man"]};

Ayarlamak

Dizgeli nesneyi şununla kodlayın: encodeURIComponent () öznitelik olarak ayarlayın:

var data_str = encodeURIComponent(JSON.stringify(my_object));
$("div#mydiv").attr("data-hero",data-str);

Almak

Değeri bir nesne olarak almak için, decodeURIComponent () , öznitelik değeri ile kodu çözülen değeri ayrıştırın :

var data_str = $("div#mydiv").attr("data-hero");
var my_object = JSON.parse(decodeURIComponent(data_str));

14

Tefrika veri saklama ile ilgili sorunlar bir çok dönüştürme çözülebilir seri dizi ile base64 .

Base64 dizesi hemen hemen her yerde karışıklık olmadan kabul edilebilir.

Şuna baksana:

WindowOrWorkerGlobalScope.btoa()Yöntem dizede her karakter ikili veri bir bayt olarak kabul edilir olan bir String nesnesi bir temel 64, kodlanmış bir ASCII dize oluşturur.

WindowOrWorkerGlobalScope.atob()İşlev kodunu çözer temel 64 kodlaması kullanılarak kodlanmış bir veri dizisi.

Gerektiği gibi dönüştürün.


Bu, karmaşık Nesneleri özniteliklere geçirmek için gerçekten işe yarar.
baacke

Ne yazık ki, önyüklemede Unicode sorunu var ve tüm diller için uygun değil.
AhmadJavadiNejad

Tarayıcı kullanımı içinwindow.btoa
Henry

1
Bu yöntem oldukça kurşun geçirmez bir IMO'dur. Ancak, base64 dizenizi aldığınızda ve kodunu çözdüğünüzde, JSON'u serileştirmiş olursunuz. Dolayısıyla JSON.parse, sonucu bir nesne olarak kullanmadan önce kullanmanız gerekir .
Henry

13

Benim için böyle çalışıyor, çünkü onu şablonda saklamam gerekiyor ...

// Generate HTML
var gridHtml = '<div data-dataObj=\''+JSON.stringify(dataObj).replace(/'/g, "\\'");+'\'></div>';

// Later
var dataObj = $('div').data('dataObj'); // jQuery automatically unescape it

1
paylaştığınız için teşekkürler .. tam olarak aradığım şey ... kabul edilen cevabı ayrıştırmaya çalışırken [Nesne Nesnesi] almaya devam etti.
greatKing

@greaterKing JSON'u kabul edilen yanıttan ayrıştırmazsanız, ona yalnızca veri adıyla aynı olan anahtar aracılığıyla erişirsiniz, böylece örneğin $('body').data('myData', { h: "hello", w: "world" })_____________________________________________________________________________________________ varsa JSON nesnenizi$('body').data().myData
jave.web

Basitleştirmek için yapabilirsiniz '<div data-dataObj=\''+ JSON.stringify(dataObj) +'\'></div>'. Bunların hepsi tek alıntılar, başlangıç ​​ve bitiş sadece kaçtı, bu yüzden sahip olmakla aynı olacaktır'{"some":"thing"}'
IamFace

1
@IamFace - replace()tamamen mümkün olan json verilerinde görünen tek tırnak olasılığını ele alır.
billynoah

3

Benim için püf noktası, anahtarların ve değerlerin etrafına çift tırnak eklemekti . Bir PHP işlevi kullanırsanız json_encode, size JSON ile kodlanmış bir dize ve sizinkini nasıl doğru bir şekilde kodlayacağınız konusunda bir fikir verecektir.

jQuery('#elm-id').data('datakey') dize, json olarak doğru şekilde kodlanmışsa, dizenin bir nesnesini döndürür.

JQuery belgelerine göre: ( http://api.jquery.com/jquery.parsejson/ )

Hatalı biçimlendirilmiş bir JSON dizesinin iletilmesi, bir JavaScript istisnasının atılmasına neden olur. Örneğin, aşağıdakilerin tümü geçersiz JSON dizeleridir:

  1. "{test: 1}"( testetrafında çift tırnak yoktur).
  2. "{'test': 1}"( 'test'çift ​​tırnak yerine tek tırnak kullanıyor).
  3. "'test'"( 'test'çift ​​tırnak yerine tek tırnak kullanıyor).
  4. ".1"(bir sayı bir rakamla başlamalıdır; "0.1"geçerli olacaktır).
  5. "undefined"( undefinedJSON dizesinde temsil edilemez; nullancak olabilir).
  6. "NaN"( NaNJSON dizesinde temsil edilemez; Infinity'nin doğrudan temsili de n'dir

2

Kullanımını birleştirin window.btoave window.atobile buluşmanızı JSON.stringifyve JSON.parse.

- Bu, tek tırnak içeren dizeler için çalışır

Verilerin kodlanması:

var encodedObject = window.btoa(JSON.stringify(dataObject));

Verilerin kodunu çözmek:

var dataObject = JSON.parse(window.atob(encodedObject));

Verilerin daha sonra click olayıyla nasıl oluşturulduğuna ve kodunun nasıl çözüldüğüne ilişkin bir örnek aşağıda verilmiştir.

HTML'yi oluşturun ve verileri kodlayın:

var encodedObject = window.btoa(JSON.stringify(dataObject));

"<td>" + "<a class='eventClass' href='#' data-topic='" + encodedObject + "'>" 
+ "Edit</a></td>"

Tıklama olay işleyicisindeki verilerin kodunu çözün:

$("#someElementID").on('click', 'eventClass', function(e) {
            event.preventDefault();
            var encodedObject = e.target.attributes["data-topic"].value;
            var dataObject = JSON.parse(window.atob(encodedObject));

            // use the dataObject["keyName"] 
}

0

Kullanılması belgelenmiş jQuery .data (obj) sözdizimi Eğer DOM öğesindeki bir nesneyi depolamasına izin verir. Öğenin data-incelenmesi, nesnenin değeri için herhangi bir anahtar belirtilmediğinden özniteliği göstermez . Ancak, nesne içindeki verilere anahtar ile referans verilebilir .data("foo")veya nesnenin tamamı ile döndürülebilir.data() .

Öyleyse bir döngü oluşturduğunuzu ve result[i] = { name: "image_name" }:

$('.delete')[i].data(results[i]); // => <button class="delete">Delete</delete>
$('.delete')[i].data('name'); // => "image_name"
$('.delete')[i].data(); // => { name: "image_name" }

0

Bazı nedenlerden dolayı, kabul edilen cevap sadece sayfada bir kez kullanılıyorsa benim için işe yaradı, ancak benim durumumda sayfadaki birçok öğeye veri kaydetmeye çalışıyordum ve veriler ilk öğe dışında bir şekilde kayboldu.

Alternatif olarak, verileri doma yazıp gerektiğinde tekrar ayrıştırdım. Belki daha az verimli, ancak amacım için iyi çalıştı çünkü gerçekten verilerin prototipini oluşturuyorum ve bunu üretim için yazmıyorum.

Kullandığım verileri kaydetmek için:

$('#myElement').attr('data-key', JSON.stringify(jsonObject));

Daha sonra verileri geri okumak, kabul edilen cevapla aynıdır, yani:

var getBackMyJSON = $('#myElement').data('key');

Öğeyi Chrome'un hata ayıklayıcısıyla inceleyecek olursam, bu şekilde yapmak, verilerin de etki alanında görünmesini sağladı.


0

.data()çoğu durumda mükemmel çalışır. Tek sorun yaşadığım an, JSON dizesinin kendisinde tek bir alıntı olduğu zamandı. Bunu aşmanın kolay bir yolunu bulamadım, bu yüzden bu yaklaşıma başvurdum (sunucu dili olarak Coldfusion kullanıyorum):

    <!DOCTYPE html>
        <html>
            <head>
                <title>
                    Special Chars in Data Attribute
                </title>
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
                <script>
                    $(function(){
                        var o = $("##xxx");
                        /**
                            1. get the data attribute as a string using attr()
                            2. unescape
                            3. convert unescaped string back to object
                            4. set the original data attribute to future calls get it as JSON.
                        */
                        o.data("xxx",jQuery.parseJSON(unescape(o.attr("data-xxx"))));
                        console.log(o.data("xxx")); // this is JSON object.
                    });
                </script>
                <title>
                    Title of the document
                </title>
            </head>
            <body>
                <cfset str = {name:"o'reilly's stuff",code:1}>
<!-- urlencode is a CF function to UTF8 the string, serializeJSON converts object to strin -->
                <div id="xxx" data-xxx='#urlencodedformat(serializejson(str))#'>
                </div>
            </body>
        </html>

0

Kayıt için aşağıdaki kodun işe yaradığını buldum. Diziyi veri etiketinden almanızı, yeni bir öğeyi göndermenizi ve doğru JSON biçiminde veri etiketinde saklamanızı sağlar. Bu nedenle, aynı kod, istenirse diziye başka öğeler eklemek için yeniden kullanılabilir. $('#my-data-div').attr('data-namesarray', names_string);Diziyi doğru bir şekilde sakladığını ancak $('#my-data-div').data('namesarray', names_string);çalışmadığını buldum .

<div id="my-data-div" data-namesarray='[]'></div>

var names_array = $('#my-data-div').data('namesarray');
names_array.push("Baz Smith");
var names_string = JSON.stringify(names_array);
$('#my-data-div').attr('data-namesarray', names_string);

0
!DOCTYPE html>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
$("#btn1").click(function()
{
person = new Object();
person.name = "vishal";
person.age =20;
    $("div").data(person);
});
  $("#btn2").click(function()
{
    alert($("div").data("name"));
});

});

</script>
<body>
<button id="btn1">Attach data to div element</button><br>
<button id="btn2">Get data attached to div element</button>
<div></div>
</body>


</html>

Anser:-Attach data to selected elements using an object with name/value pairs.
GET value using object propetis like name,age etc...

0

Bu kod benim için iyi çalışıyor.

Verileri btoa ile kodlayın

let data_str = btoa(JSON.stringify(jsonData));
$("#target_id").attr('data-json', data_str);

Ve sonra atob ile çöz

let tourData = $(this).data("json");
tourData = atob(tourData);

Ne yazık ki, önyüklemede Unicode sorunu var ve tüm diller için uygun değil.
AhmadJavadiNejad
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.