Вывод JSON Объекта из localStorage
Вобщем надо вывести все объекты из локалстоража...Если применяю $.parseJSON(); к переменной value - выдает undefined, если нет, то выводит тупо весь JSON объект из значения строкой. Что не так?
// JavaScript Document $(document).ready(function(){ function isLocalStorageAvailable(){ try { return 'localStorage' in window && window['localStorage'] !== null; } catch (e) { return false; } } try { //localStorage.setItem('foo', 'bar'); } catch (e) { if (e == QUOTA_EXCEEDED_ERR) { alert('Локальное хранилище переполнено'); } } $.getJSON( 'json/posts.json', function(data){ var posts = ''; $.each(data, function(postIndex, post) { localStorage.setItem('post_id'+post['id'], JSON.stringify(post)); posts += localStorage['post_id'+post['id']]; //var local = $.parseJSON(posts); //alert(local); }) var ololo = $.parseJSON(localStorage['post_id1']); alert(ololo.title); var obj = window.localStorage; for(var key in obj){ value = localStorage[key]; alert(key +'=>'+value); alert('Ошибка где-то до этой строки.'); }; for (var i = 0; i < localStorage.length; i++) { alert(localStorage[i] + " = " + $.parseJSON(localStorage[localStorage[i]])); $.each($.parseJSON(localStorage[localStorage[i]]), function(eIndex, e) { alert(e.title); }); } //for(var i=1, len=localStorage.length; i<len; i++) { // var value = $.parseJSON(localStorage['post_id'+i]); // $.each(value, function(eIndex, e) { // alert(e.title); // }); //} //var local = $.parseJSON(posts); alert(posts); //posts += localStorage.setItem('posts', JSON.stringify(data)) //var local = $.parseJSON(localStorage.getItem('posts')); //formatposts = $.parseJSON(posts); //alert(formatposts); //for(i=0; i<posts.length; i++){ // alert(posts[i]); //} $.each(posts, function(entryIndex, entry) { var post = '<article><header><h3>'; post += entry['title']+'</h3></header><section><p>'; post += entry['body']+'</p></section><footer>'; if(entry['tags']){ post += '<div id="tags">'; $.each(entry['tags'], function(tagIndex, tag){ post += '<span class="label">' + tag + '</span>' }); post += '</div><div class="controls"><a class="btn btn-danger btn-mini">удалить</a></div>'; } post += '</footer></article>'; $('#posts').append(post); }); }); }); Вот можете посмотреть сами http://smirnoff.ho.ua/JSUI/ |
JSON !== объект.
Вы формат соблюли? |
разве? Хм...подскажите тогда в чем ошибка, как мне исправить код?
|
попробуйте превращать строку в объект
JSON.parse(..) // или так eval("("+ .... +")"); |
Так я же так и превращаю через $.parseJSON(), и мне выдает [Object object] вместо значений ключа, в перемечшку с кучей undefined и в самом конце один раз таки выводит заголовки
|
объекты вложенные? т.е. есть такое, что значением является объект?если да, то это плохо
|
Эм..ну собственно каждое значение JSON объект, причем в каждом есть значение, являющееся массивом. Т.к. хранилище заполняется из JSON файла. Вот код JSON файла собственно, дабы лучше понять картину:
[ { "id": 1, "title": "Стремящийся наибольший", "body": "Поле направлений нейтрализует коллинеарный полином, откуда следует доказываемое равенство.", "tags": [ "тег", "еще тег" ] }, { "id": 2, "title": "Эффузивный топаз", "body": "Поскольку плиты перестали сближаться, гейзер сдвигает кимберлит, в соответствии с изменениями в суммарной минерализации.", "tags": [ "коренной цоколь", "дифференциация", "апатит" ] }, { "id": 3, "title": "Звукорядный октавер", "body": "Ретро монотонно диссонирует форшлаг, и здесь в качестве модуса конструктивных элементов используется ряд каких-либо единых длительностей.", "tags": [ "конструктивный соноропериод", "движение" ] }, { "id": 4, "title": "Спиральный фотон", "body": "Любое возмущение затухает, если взрыв ненаблюдаемо искажает экранированный электрон, и это неудивительно, если вспомнить.", "tags": [ "сверхновая", "гидродинамический удар" ] } ] А почему плохо? И да, если что в верху страницы собственно видно требование задания. В хранилище я сделал запись каждого поста, т.е. каждого объекта, и выглядит следующим образом: post_id1 => {"id":1,"title":"Стремящийся наибольший","body":"Поле направлений нейтрализует коллинеарный полином, откуда следует доказываемое равенство.","tags":["тег","еще тег"]} |
Здесь да, это я специально тестил и выводил отдельный пост
|
Хм...у Вас в конце перебирается переменная data в которой JSON массив, а надо же перебирать локалстораж, ведь посты будут добавлятся, удалятся и соответственно выводить надо работая ТОЛЬКО с локалсторажем. Заполнили в первый раз значениями базовыми из JSON файла, и все далее только с локалсторажем работаем
|
ошибки вот здесь :
for (var i = 0; i < localStorage.length; i++) { alert(localStorage[i] + " = " + $.parseJSON(localStorage[localStorage[i]])); $.each($.parseJSON(localStorage[localStorage[i]]), function(eIndex, e) { alert(e.title); }); } ибо i - число, и localStorage[ число ] не существует, ибо сохраняли с ключом вида 'post_id'+post['id'] и итерация начинается с нуля, а ID'шники погут случайным образом попадаться, т.е. простой итерацией тут не спастись. но, ели хотите, можно так: i + 1. идем далее. $.parseJSON(localStorage[localStorage[i]] это что такое? допустим i исправили, localStorage["post_id"+(i+1)] возвратит строку объекта. далее получаем undefined из внешнего (первого слева) localStorage, и пытаемся из этого undefined взять JSON. ошибочка. вот так пойдёт $.parseJSON(localStorage["post_id" + (i + 1)]) |
Дык это ж закоммеченный блок, я уже понял что это не решение.
|
Подскажите плз ,как же правильно вывести данные?
|
писалось на коленке, может не работать. ну, я проверил в консоли, на сайте JQ, работает :)
только хоть с JQ, хоть без неё, для старых браузеров нужно искать имплементацию JSON.stringify на JS. сохраняем так : http://api.jquery.com/jQuery.map/ var postIds, prefix = "post_id_", postsIds_key = "post_ids"; postIds = $.map(data, function (post) { var stringified = JSON.stringify(post); localStorage.setItem(prefix + post.id, stringified); return post.id; }); postIds = JSON.stringify(postIds); // в принципе, можно было и join'ом localStorage.setItem(postsIds_key, postIds); достаем так: var postIds, posts; // prefix определён выше. // postsIds_key тоже определён выше. postIds = localStorage.getItem(postsIds_key); if (postIds) { postIds = JSON.parse(postIds); posts = $.map(postIds, function (postId) { var post; post = localStorage.getItem(prefix + postId); post = JSON.parse(post); return post; }); } else { /* нет сохранённых ID'шников */ } |
Хм...не совсем понятна эта строка:
var stringified = JSON.stringify(post); Как мне быть в моем случае, ведь у меня как видели идет заполнение из JSON файла, содержание которог оя кинул...или мне достаточно попробовать воспользоватся вашим куском кода, отвечающим за вывод? ЗЫ: попробовал - все равно [object] и андефайнд |
Цитата:
{ "id": 1, "title": "Стремящийся наибольший", "body": "Поле направлений нейтрализует коллинеарный полином, откуда следует доказываемое равенство.", "tags": [ "тег", "еще тег" ] } // стало '{"id":1,"title":"Стремящийся наибольший","body":"Поле направлений нейтрализует коллинеарный полином, откуда следует доказываемое равенство.","tags":["тег","еще тег"]}' Цитата:
|
Хм...чтото нифига не выходит( Вообще теперь ничего не выводит и не происходит. Код стал таким:
// JavaScript Document $(document).ready(function(){ function isLocalStorageAvailable(){ try { return 'localStorage' in window && window['localStorage'] !== null; } catch (e) { return false; } } try { //localStorage.setItem('foo', 'bar'); } catch (e) { if (e == QUOTA_EXCEEDED_ERR) { alert('Локальное хранилище переполнено'); } } $.getJSON( 'json/posts.json', function(data){ var prefix = "post_id", postsIds_key = "post_ids"; $.each(data, function(postIndex, post) { localStorage.setItem('post_id'+post['id'], JSON.stringify(post)); posts += localStorage['post_id'+post['id']]; }) var postIds, posts; // prefix определён выше. // postsIds_key тоже определён выше. postIds = localStorage.getItem(postsIds_key); if (postIds) { postIds = JSON.parse(postIds); posts = $.map(postIds, function (postId) { var post; post = localStorage.getItem(prefix + postId); post = JSON.parse(post); return post; }); } else { /* нет сохранённых ID'шников */ } alert(post); var ololo = $.parseJSON(localStorage['post_id1']); //alert(ololo.title); alert(posts); $.each(posts, function(entryIndex, entry) { var post = '<article><header><h3>'; post += entry['title']+'</h3></header><section><p>'; post += entry['body']+'</p></section><footer>'; if(entry['tags']){ post += '<div id="tags">'; $.each(entry['tags'], function(tagIndex, tag){ post += '<span class="label">' + tag + '</span>' }); post += '</div><div class="controls"><a class="btn btn-danger btn-mini">удалить</a></div>'; } post += '</footer></article>'; $('#posts').append(post); }); }); }); |
неправильно сохраняете. чтобы работало восстановление, нужно сохранять так же, как я написал. эти 2 куска кода взаимосвязаны
|
Хм...попробовал весь Ваш код вместо своего. Работает! Теперь тогда таков вопрос..внизу форму добавления поста..и кнопка удаления.. Как реализовать так, чтобы кнопка удаления удаляла именно свой пост?
|
в атрибут записать ID поста, к которому она относится.
дальше просто удалить элемент (пост) со страницы, удалить его из хранилища, и подправить массив postIds : если не исправлять массив postIds, тогда будем иметь в нём мёртвые ID'шники постов. оно Вам надо? $delete_button.parents("article").remove(); // для начала удалим пост со страницы. /* можно даже проанимировать $delete_button.parents("article").slideUp("slow", function () { $(this).remove(); }); */ var id = $delete_button.attr(...); // получим тут 3, например - ID поста, к которому относится кнопка. вместо троеточия пишем атрибут, в котором сохранён ID. localStorage.removeItem(prefix + id); // удалим пост из хранилища // теперь удалим значение из массива. // postIds должен быть уже получен ранее. var index = postIds.indexOf(id); postIds.splice(index, 1); // удалили // теперь сохраним измененный массив в хранилище. можно сразу localStorage.setItem(postsIds_key, postIds); |
Спасибо! Сейчас попробую....и ещё 2 вопроса...Как сделать так, чтобы хранилище заполнялось базовыми данными из JSON файла, только первый раз, а потом, если уже заполнено - то не трогало его...и по поводу добавления поста..я не совсем понимаю... Форма добавления состоит из таких полей:
<input type="text" name="title" class="span4" placeholder="заголовок"><br> <textarea name="body" rows="3" class="span4" placeholder="запись"></textarea><br> <input type="text" name="tags" class="span4" placeholder="тег, еще тег"><br><br> <button type="submit" class="btn btn-primary">добавить</button> Выходит Записывать в хранилище надо как-то вот так?: var post =$('#zagol').val(); var post +=$('#body').val(); var post +=$('#tags').val(); $('.btn-primary').click(function(){ var stringified = JSON.stringify(post); localStorage.setItem(prefix + post.id, stringified); }); Хотя как же тогда брать пост id... |
в коде, где достаем записи из хранилища :
Цитата:
Цитата:
что-то вроде такого : var post = { title: $("#zagol").val(), body: $("#body").val(), ..... } и да, только получение текста ( bla bla.val() + bla.val() ) нужно делать в обработчике клика, иначе пустые значения будут. Цитата:
post.id = postIds ? postIds[postIds - 1] + 1 : 0; |
Цитата:
|
Попробовал..но теперь посты вообще не выводятся. Да и хранилище почему то опустело. Код изменил вот так:
// JavaScript Document $(document).ready(function(){ var post, postIds, prefix = "post_id_", postsIds_key = "post_ids"; postIds = $.map(data, function (post) { var stringified = JSON.stringify(post); localStorage.setItem(prefix + post.id, stringified); return post.id; }); postIds = JSON.stringify(postIds); // в принципе, можно было и join'ом localStorage.setItem(postsIds_key, postIds); var postIds, posts; //prefix определён выше. //postsIds_key тоже определён выше. postIds = localStorage.getItem(postsIds_key); if (postIds) { postIds = JSON.parse(postIds); posts = $.map(postIds, function (postId) { post = localStorage.getItem(prefix + postId); post = JSON.parse(post); return post; }); } else { $.getJSON( 'json/posts.json', function(data){ $.each(data, function(postIndex, post) { localStorage.setItem('post_id'+post['id'], JSON.stringify(post)); posts += localStorage['post_id'+post['id']]; }) }); } //Выводим посты $.each(posts, function(entryIndex, entry) { post = '<article><header><h3>'; post += entry['title']+'</h3></header><section><p>'; post += entry['body']+'</p></section><footer>'; if(entry['tags']){ post += '<div id="tags">'; $.each(entry['tags'], function(tagIndex, tag){ post += '<span class="label">' + tag + '</span>' }); post += '</div><div class="controls"><a class="btn btn-danger btn-mini">удалить</a></div>'; } post += '</footer></article>'; $('#posts').append(post); }); }); |
Цитата:
Цитата:
|
Я написал выше что непонятно..но видимо остальное не так понимаю...сейчас вот немного изменил код опять(но мне кажется не правильно..но посты в хранилище записываются..но не выводятся..( и да, значение ключа post_ids стало почему то undefined)что ж опять не так в коде? Сейчас нужно хотя бы так изменить код, чтобы просто выводил сохраненные уже в хранилище базовые значения из JSON файла, потом уже на клик просто добавить код добавления поста.
// JavaScript Document $(document).ready(function(){ var post, posts, postIds, prefix = "post_id_", postsIds_key = "post_ids"; //Доавление постов в localStorage $.getJSON( 'json/posts.json', function(data){ postIds = $.map(data, function (post) { var stringified = JSON.stringify(post); localStorage.setItem(prefix + post.id, stringified); return post.id; }); }); postIds = JSON.stringify(postIds); // в принципе, можно было и join'ом localStorage.setItem(postsIds_key, postIds); postIds = localStorage.getItem(postsIds_key); if (postIds) { postIds = JSON.parse(postIds); posts = $.map(postIds, function (postId) { post = localStorage.getItem(prefix + postId); post = JSON.parse(post); return post; }); } else { $.getJSON( 'json/posts.json', function(data){ $.each(data, function(postIndex, post) { localStorage.setItem('post_id'+post['id'], JSON.stringify(post)); posts += localStorage['post_id'+post['id']]; }) }); } //Выводим посты $.each(posts, function(entryIndex, entry) { var html = '<article><header><h3>'; html += entry['title']+'</h3></header><section><p>'; html += entry['body']+'</p></section><footer>'; if(entry['tags']){ html += '<div id="tags">'; $.each(entry['tags'], function(tagIndex, tag){ html += '<span class="label">' + tag + '</span>' }); html += '</div><div class="controls"><a class="btn btn-danger btn-mini">удалить</a></div>'; } html += '</footer></article>'; $('#posts').append(html); }); }); |
Хм....сейчас сам попытался опять изменить...выводило..попроб� �вал добавить функцию добавления поста при клике...Но, посты перестали выводится, а в хранилище появилось:
post_id_NaN =>[""] post_id_undefined=>"" post_ids=>NaN И в итоге посты не выводятся( Вот весь код: // JavaScript Document $(document).ready(function(){ //$.getJSON( // 'json/posts.json', // function(data){ //var prefix = "post_id", postsIds_key = "post_ids"; var post, postIds, prefix = "post_id_", postsIds_key = "post_ids"; // postIds = $.map(data, function (post) { // var stringified = JSON.stringify(post); // localStorage.setItem(prefix + post.id, stringified); // return post.id; // }); postIds = JSON.stringify(postIds); // в принципе, можно было и join'ом //localStorage.setItem(postsIds_key, postIds); //$.each(data, function(postIndex, post) { // localStorage.setItem('post_id'+post['id'], JSON.stringify(post)); // posts += localStorage['post_id'+post['id']]; //}) // prefix определён выше. // postsIds_key тоже определён выше. postIds = localStorage.getItem(postsIds_key); if (postIds) { postIds = JSON.parse(postIds); posts = $.map(postIds, function (postId) { var post; post = localStorage.getItem(prefix + postId); post = JSON.parse(post); return post; }); } else { $.getJSON( 'json/posts.json', function(data){ postIds = $.map(data, function (post) { var stringified = JSON.stringify(post); localStorage.setItem(prefix + post.id, stringified); return post.id; }); }); localStorage.setItem(postsIds_key, postIds); } $.each(posts, function(entryIndex, entry) { var html = '<article><header><h3>'; html += entry['title']+'</h3></header><section><p>'; html += entry['body']+'</p></section><footer>'; if(entry['tags']){ html += '<div id="tags">'; $.each(entry['tags'], function(tagIndex, tag){ html += '<span class="label">' + tag + '</span>' }); html += '</div><div class="controls"><a class="btn btn-danger btn-mini">удалить</a></div>'; } html += '</footer></article>'; $('#posts').append(html); }); //}); //Добавление поста $('button[type="submit"]').click(function(){ var post ={ title: $('#zagol').val(), body: $("#body").val(), tags: $('#tags').val() } postIds = $.map(post, function (post) { var stringified = JSON.stringify(post); post.id = postIds ? postIds[postIds - 1] + 1 : 0; localStorage.setItem(prefix + post.id, stringified); return post.id; }); postIds = JSON.stringify(postIds); localStorage.setItem(postsIds_key, postIds); }); }); |
Философ,
Не вникал в тему, но был собственный опыт сохранения именно постов в localStorage в формате base64. Парсицо достаточно быстро, разница в визуальном отображений ( для постов более страницы) фактически не заметна Рабочий пакер - пост 21 самый низ=> http://javascript.ru/forum/misc/2931...tml#post185226 |
и также с тегами? Хм..подскажите тогда что ж у меня не так?
|
Цитата:
|
переписал всё. если не будет работать - напишите в начале функции debugger, откройте консоль и перезагрузите страницу. дальше поэтапно смотрите, что делает скрипт, и где ошибка.
$(function () { var post, posts, postIds, prefix = "post_id_", postsIds_key = "post_ids"; // --------------------------- // выведет на страницу посты из массива постов (data, или posts) // --------------------------- function parsePosts (posts) { $.each(posts, function (index, post) { var html = '<article><header><h3>'; html += post.title + '</h3></header><section><p>'; html += post.body + '</p></section><footer>'; if (post.tags) { html += '<div id="tags">'; if (!$.isArray(post.tags)) { post.tags = post.tags || ""; post.tags = [post.tags]; } $.each(post.ags, function (tagIndex, tag) { html += '<span class="label">' + tag + '</span>'; }); html += '</div><div class="controls"><a class="btn btn-danger btn-mini remove" post_id="' + post.id + '">удалить</a></div>'; } html += '</footer></article>'; $('#posts').append(html); }); } // --------------------------- // получение списка постов // --------------------------- // получаем список идентификаторов постов из хранилища postIds = localStorage.getItem(postsIds_key); if (postIds) { // есть в хранилище. обрабатываем и выводим на страницу. postIds = JSON.stringify(postIds); postIds = JSON.parse(postIds); posts = $.map(postIds, function (postId) { post = localStorage.getItem(prefix + postId); post = JSON.parse(post); return post; }); parsePosts(posts); } else { // его нет в хранилище. делаем запрос ... $.getJSON('json/posts.json', function (data) { // и, когда данные придут, записываем посты в хранилище postIds = $.map(data, function (post) { var stringified = JSON.stringify(post); localStorage.setItem(prefix + post.id, stringified); return post.id; }); // сохраняем идентификаторы постов в хранилище. localStorage.setItem(postsIds_key, JSON.stringify(postIds)); // и выводим посты на страницу. posts = data; parsePosts(posts); }); } // --------------------------- // делегируем клик по кнопке "удалить" // --------------------------- $("body").on("click", ".controls .remove[post_id]", function (e) { var $this = $(e.target); // красиво удаляем пост со страницы $this.parents("article").slideUp("slow", function () { $(this).remove(); }); // ID поста. var id = $this.attr("post_id"); // удалим пост из хранилища localStorage.removeItem(prefix + id); // теперь удалим значение из списка идентификаторов var index = postIds.indexOf(id); postIds.splice(index, 1); // удалили // теперь сохраним измененный список в хранилище. localStorage.setItem(postsIds_key, postIds); }); // --------------------------- // делегируем клик по кнопке добавления поста // --------------------------- $("body").on("click", "button[type=submit]", function () { var title = $('#zagol'), body = $("#body"), tags = $('#tags'); var post ={ title: title.val(), body: body.val(), tags: tags.val(), id: postIds[postIds.length - 1] + 1 }; // добавляем идентификатор постов в список и сохраняем postIds.push(post.id); localStorage.setItem(postsIds_key, JSON.stringify(postIds)); // сохраняем новый пост в хранилище. localStorage.setItem(prefix + post.id, JSON.stringify(post)); // выводим его на страницу parsePosts( [post] ); // -> parsePosts принимает массив, поэтому [post] // очищаем форму title.add(body).add(tags).val(""); }); }); |
Цитата:
|
Спасибо! Попробовал..но увы, посты не выводятся, хотя локалстораж заполнен базовыми данными. Написал debugger в начале функции, как вы и сказали, но..никаких ошибок нет.. консоль пуста, и перекидывает на вкладку scripts и конкретно на строчку с debugger; в отладчике хрома. Пробовал добавить пост - тоже ни в DOM не добавляется, ни в хранилище. Без дебаггера выдает ошибку Uncaught TypeError: Cannot read property 'length' of undefined в файле джиквери.
|
Цитата:
|
Цитата:
|
Так что же всетаки не так с выводом?
|
Ребята, такая же проблема возникла как и у Философ. В IE 10 отладчик говорит, что localStorage undefined в этом месте
Код:
postIds = localStorage.getItem(postsIds_key); |
Что непонятного в сообщении - "localStorage undefined" ?
обычно это происходит при неверно указанном доктайпе |
Часовой пояс GMT +3, время: 05:23. |