2011-12-17 12 views
96

Jestem przechowywania danych z wykorzystaniem podejścia data- w znaczniku HTML tak:Store JSON obiekt w atrybucie danych w HTML jQuery

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

ja wtedy pobierania danych w zwrotnego tak:

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

To działa dobrze. Utknąłem na tym, że próbuję zapisać obiekt zamiast tylko jednej z jego właściwości. Próbowałem to zrobić:

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

Potem próbował uzyskać dostęp do właściwości name tak:

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

Dziennik mówi mi undefined. Tak więc wydaje się, że można przechowywać proste ciągi w atrybutach data- ale nie mogę przechowywać obiekty JSON ...

Próbowałem również użyć tego dzieciaka składni bez powodzenia:

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

Masz pomysł na przechowywanie rzeczywistego obiektu w tagu HTML za pomocą podejścia data-?

Odpowiedz

99

zamiast osadzania go w tekście wystarczy użyć $('#myElement').data('key',jsonObject);

nie będzie faktycznie być przechowywane w html, ale jeśli używasz jquery.data, że ​​wszyscy są wydobywane w każdym razie.

Aby uzyskać JSON powrotem nie przetworzy go, zadzwoń:

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

Jeśli otrzymujesz [Object Object] zamiast bezpośredniego JSON, tylko dostęp do JSON przez klucz danych:

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

Więc używając data- podejście pozwala mi zapisać wartość dla każdego przycisku delete (każdy przycisk robi inny obiekt JSON ...) Mam w tabeli umieszczając znacznik hmtl, tak jak pokazałem powyżej.Czy to co sugerujesz pozwoli mi powiązać każdy obiekt z odpowiednim przyciskiem usuwania? Jak to zrobić , jak bym użył $ ("# myElement") w taki sam sposób? Niestety, nie jestem doświadczony w tym. Dzięki – zumzum

+0

Tak więc skończyłem przypisywanie indeksu do każdego przycisku html: i przechowywanie tablicy obiektów JSON w zmiennej $ objects. Po kliknięciu przycisku patrzę na indeks przycisków, wykonując: var buttonIndex = $ (this) .data ('index'); a następnie otrzymuję odpowiedni obiekt z wcześniej zapisanego w ten sposób: $ objects [buttonIndex]. Działa to dobrze, nie wiem, czy jest to właściwy sposób. Dziekuję za odpowiedź! – zumzum

108

Faktycznie, twój ostatni przykład:

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

wydaje się działać dobrze (patrz http://jsfiddle.net/GlauberRocha/Q6kKU/).

Dobrze, że ciąg w atrybucie danych jest automatycznie konwertowany na obiekt JavaScript. Nie widzę żadnych wad w tym podejściu, wręcz przeciwnie! Jeden atrybut jest wystarczający do przechowywania całego zestawu danych, gotowego do użycia w JavaScript przez właściwości obiektu.

(Uwaga: dla atrybutów danych należy automatycznie podawać typ Object zamiast String, należy zachować ostrożność przy pisaniu poprawnego JSON, w szczególności w celu ujęcia nazw kluczy w podwójnych cudzysłowach).

+15

Jeśli to pomaga każdemu, oto jak uzyskać dostęp do powyższego: '$ ('div') .danych ('foobar') .foo'. http://api.jquery.com/data/ – Gary

+0

@GlauberRocha co jeśli w obiekcie data-foobar były dwa elementy i chciałeś usunąć tylko jeden element ... w jaki sposób to zrobiłeś? –

+0

Gdy dane w twoim znaczniku są dostępne jako obiekt javascript ('var foobar = $ ('div') .dane ('foobar')'), możesz użyć operatora ** delete **, aby usunąć właściwość: 'delete foobar.foo' (lub' delete foobar ['foo'] ') lub rób co chcesz z tym. –

9

Dla mnie to działa tak, jak muszę przechowywać je w szablonie ...

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

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

dziękuję za udostępnienie ... dokładnie to, czego szukałem ... uzyskiwałem [Object Object], próbując przeanalizować zaakceptowaną odpowiedź. – greaterKing

+0

@greaterKing nie analizować JSON z zaakceptowanej odpowiedzi, wystarczy uzyskać dostęp za pomocą klucza, który jest taki sam jak nazwa danych, więc jeśli masz np. '$ ('body'). data (" myData ", {h:" hello ", w:" world "})' _____________________________________________________________________________________________ uzyskałbyś swój obiekt JSON przez '$ ('body'). data(). myData ' –

+0

Aby uprościć, możesz wykonać' '

''. Wszystkie są pojedynczymi cytatami, początek i koniec są po prostu uciekane, więc byłoby to tak samo jak "{" niektóre ":" rzecz "} '' – IamFace

0

Używanie documented jquery .data(obj) syntax pozwala przechowywać obiekt na elemencie DOM. Sprawdzanie elementu nie wyświetli atrybutu data-, ponieważ nie ma klucza określonego dla wartości obiektu.Jednak do danych w obiekcie można się odwoływać klawiszem o numerze .data("foo") lub cały obiekt można zwrócić przy pomocy .data().

Więc zakładając skonfigurować pętlę i 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

Z jakiegoś powodu, zaakceptowane odpowiedź pracował dla mnie tylko wtedy, gdy jest stosowany raz na stronie, ale w moim przypadku starałem się zapisać dane na wielu elementach na stronie i dane zostały w jakiś sposób utracone na wszystkich oprócz pierwszego elementu.

Alternatywnie, zapisałem dane w domenie i przeanalizowałem je w razie potrzeby. Być może jest to mniej wydajne, ale działa dobrze dla mojego celu, ponieważ naprawdę prototypuję dane i nie piszę tego do produkcji.

Aby zapisać dane użyłem:

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

Aby następnie odczytać dane z powrotem jest taka sama jak zaakceptowanej odpowiedzi, a mianowicie:

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

Robi to w ten sposób wykonany również pojawić się dane w domenie, gdybym miał sprawdzić element za pomocą debuggera Chrome.

0

działa doskonale w większości przypadków. Jedyny raz miałem problem, gdy sam ciąg JSON miał pojedynczy cytat. Nie mogłem znaleźć żadnych łatwy sposób ominąć to więc uciekają się do tej metody (Używam ColdFusion może języku serwera):

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

Wiele problemów z przechowywaniem danych odcinkach może być rozwiązany poprzez przekształcenie zserializowaną ciąg base64 . Łańcuch base64 może być zaakceptowany praktycznie wszędzie bez zbędnego zamieszania. Spójrz na:

atob() 
btoa() 

Konwersja do/z zgodnie z potrzebami.

+0

Dobre rozwiązanie thnx – Sajan

6

Tak to działało dla mnie.

Aby zapisać atrybut JSON w elemencie danych HTML, Stringy obiekt JSON i zakodować go metodą "encodeURIComponent()".

Podczas odczytywania danych, dekoduj ją metodą "decodeURIComponent()" i parsuj ciąg znaków do obiektu JSON.

Przykład:

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

Zapisywanie danych:

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

Odczyt danych:

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

Dla przypomnienia, znalazłem następujący kod działa. Umożliwia pobranie tablicy z tagu danych, wepchnięcie nowego elementu i zapisanie go w tagu danych w odpowiednim formacie JSON. Ten sam kod może być zatem użyty ponownie w celu dodania kolejnych elementów do tablicy, jeśli jest to pożądane. Zauważyłem, że $('#my-data-div').attr('data-namesarray', names_string); poprawnie przechowuje tablicę, ale $('#my-data-div').data('namesarray', names_string); nie działa.

<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

Sztuką było dla mnie dodać cudzysłowie kluczy i wartości. Jeśli użyjesz funkcji php, takiej jak json_encode, otrzymasz zakodowany ciąg znaków json i pomysł, jak je kodować.

jQuery ("# ​​elm-id"). Dane ("datakey") zwróci obiekt ciągu znaków, jeśli ciąg znaków jest poprawnie zakodowany jako json.

Zgodnie z dokumentacją jQuery: (http://api.jquery.com/jquery.parsejson/)

przechodzącą w zniekształconych wyników JSON ciąg w wyjątku JavaScript wyrzucane. Na przykład, następujące są nieprawidłowe ciągi JSON:

  1. "{Test: 1}" (test nie posiada podwójne cudzysłowy wokół niego).
  2. "{ 'test' 1}" ('test' wykorzystuje pojedyncze cytaty zamiast cudzysłowach).
  3. " 'test'" ('test' jest za pomocą apostrofów zamiast cudzysłów).
  4. ”0,1" (numer musi rozpoczynać się od cyfry,«0,1»będzie prawidłowy).
  5. „nieokreślony” (nieokreślony nie może być reprezentowany w ciągu JSON zerowym, jednak może być).
  6. „NaN” (NaN nie mogą być reprezentowane w ciąg JSON; bezpośrednia reprezentacja nieskończoności jest również n