Хранение данных локально в приложении Cordova
Большинству мобильных приложений потребуется локально хранить данные, а в HTML5 появились новые опции для локального хранения данных. Для локального хранения данных в приложении Cordova мы можем использовать хранилище HTML5 в сочетании с другими механизмами, предоставляемыми плагинами.
В этом уроке я расскажу о различных способах локального хранения данных, и мы увидим, как использовать HTML5 Web Storage с плагином Cordova SQLite, создав простое приложение для создания заметок.
Различные способы хранения данных локально
Давайте разберемся с различными способами локального хранения данных:
Веб-хранилище
API веб-хранилища позволяет нам хранить пары ключ / значение как локальное хранилище и / или хранилище сеансов. Локальное хранилище является постоянным, тогда как хранилище сеансов удаляется при выходе из приложения. Веб-хранилище может хранить 2-10 МБ данных, точный лимит квот зависит от платформы.
Вы не можете хранить много данных в веб-хранилище, но легче читать и записывать в них данные.
Например : если ваше приложение состоит из нескольких файлов HTML, вы можете использовать веб-хранилище для передачи небольших объемов данных между ними.
База данных Web SQL
Web SQL API хранит и запрашивает данные с использованием SQL. Вы можете хранить 50-200 МБ данных в базе данных Web SQL, точный лимит квот зависит от платформы. Как только предел достигнут, WebView
запрашивает у пользователя разрешение использовать больше локального пространства. Этот API поддерживается не всеми платформами, но вы можете использовать WebSQL Cordova Plugin для его заполнения.
IndexedDB
IndexedDB предоставляет API для хранения и извлечения данных в виде объектов, опять же, точный предел квоты зависит от платформы. Как только предел достигнут, WebView
просит пользователя предоставить разрешение на использование большего количества локального пространства. Этот API поддерживается не всеми платформами, но вы можете использовать плагин IndexedDB Cordova для его заполнения.
Cordova File Plugin
Этот плагин Cordova реализует API-интерфейсы файловой системы HTML5 для чтения и записи данных в файлы, поэтому используйте этот плагин, если вы хотите хранить двоичные объекты.
Cordova SQLite Плагин
Этот плагин Cordova позволяет приложению Cordova получать доступ к базовой базе данных SQLite, предоставляя API, идентичный API Web SQL. Он не имеет ограничения по квоте и может синхронизировать данные с iCloud на iOS.
В большинстве случаев вам понадобятся только API для веб-хранилища и плагин SQLite.
Примечание: для локального хранения изображений вам не нужно использовать файловый плагин. Некоторые разработчики используют схему кодирования Base64 для хранения изображений в SQLite. Но для видео, аудио и других больших файлов кодирование и декодирование занимают много времени и памяти, поэтому рекомендуется хранить их в файлах и использовать URL-адрес файла для их отображения.
Обзор веб-хранилища
Хотя вы, возможно, знакомы с API-интерфейсами веб-хранилищ, их стоит пересмотреть.
Как добавить, удалить, обновить и очистить локальное хранилище:
if(localStorage != undefined) { console.log("Local Storage is supported"); //add localStorage.setItem("Website", "SitePoint"); //update or overwrite localStorage.setItem("Website", "SitePoint.com"); //remove localStorage.removeItem("Website"); //remove all localStorage.clear(); } else { console.log("No support"); }
-if(localStorage != undefined) { console.log("Local Storage is supported"); //add localStorage.setItem("Website", "SitePoint"); //update or overwrite localStorage.setItem("Website", "SitePoint.com"); //remove localStorage.removeItem("Website"); //remove all localStorage.clear(); } else { console.log("No support"); }
Как добавить, удалить, обновить и очистить хранилище сессии:
if(sessionStorage != undefined) { console.log("session Storage is supported"); //add sessionStorage.setItem("Website", "SitePoint"); //update or overwrite sessionStorage.setItem("Website", "SitePoint.com"); //remove sessionStorage.removeItem("Website"); //remove all sessionStorage.clear(); } else { console.log("No support"); }
-if(sessionStorage != undefined) { console.log("session Storage is supported"); //add sessionStorage.setItem("Website", "SitePoint"); //update or overwrite sessionStorage.setItem("Website", "SitePoint.com"); //remove sessionStorage.removeItem("Website"); //remove all sessionStorage.clear(); } else { console.log("No support"); }
Cordova SQLite Плагин
SQLite — это встроенная СУБД, основанная на языке SQL. База данных SQLite с полным API предоставляется iOS, Android и Windows Phone.
Плагин SQLite Cordova предоставляет простой API для создания баз данных и выполнения запросов на SQLite. Этот плагин предоставляет API, похожий на API Web SQL. Вы должны быть знакомы с SQL (например, MySQL) для написания запросов.
Вот как создать базу данных и выполнить SQL-запросы к базе данных.
// Wait for plugin to load document.addEventListener("deviceready", onDeviceReady, false); // Cordova is ready function onDeviceReady() { var db = window.sqlitePlugin.openDatabase({name: "demo.db"}); db.transaction(function(tx) { //create table tx.executeSql("CREATE TABLE IF NOT EXISTS demo (id integer primary key, data text, data_num integer)", [], function(tx, res){ //insert data tx.executeSql("INSERT INTO demo (id, data, data_num) VALUES (?,?,?)", [1, "test", 100], function(tx,res){ //retrieve data tx.executeSql("SELECT * FROM demo WHERE id = ?", [1], function(tx, res){ for(var iii = 0; iii < res.rows.length; iii++) { alert(res.rows.item(iii).id); alert(res.rows.item(iii).data); alert(res.rows.item(iii).data_num); } }) }); }); }, function(err){ //errors for all transactions are reported here alert("Error: " + err.message) }); }
Здесь мы сначала создаем базу данных, затем вызываем метод transaction
объекта базы данных с обратным вызовом. Внутри обратного вызова мы запускаем запросы SQL. Запросы выполняются с использованием функции executeSql
которая возвращает ответ асинхронно.
Если какой-либо из запросов не выполняется, вызывается второй обратный вызов, переданный методу transaction
. Обратный executeSql
не будет запущен в случае сбоя запроса.
Чтобы удалить базу данных, используйте этот код:
//delete database window.sqlitePlugin.deleteDatabase({name: "demo.db"}, function(){ alert("Successfully deleted database"); }, function(){ alert("Error while delete database"); });
Создание приложения для заметок
Давайте начнем с создания приложения для заметок. Это приложение позволит пользователям добавлять и просматривать заметки.
Вы можете найти окончательный проект на GitHub .
начало
Я не буду рассказывать об установке и создании приложения Cordova. Если вы еще этого не сделали, прочитайте руководство по началу работы . Инструкции по запуску и сборке приложения доступны на той же странице.
Дайте приложению соответствующее имя и добавьте платформы, которые вы хотите поддерживать. В этом уроке я использую плагин Cordova’s Device и сторонний плагин SQLite. Запустите эту команду в каталоге проекта Cordova, чтобы установить их:
cordova plugin add cordova-plugin-device cordova plugin add cordova-plugin-sqlite
Убедитесь, что файл index.html в каталоге www выглядит следующим образом:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <title>Note</title> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"> </head> <body> <!-- put jQuery mobile pages here --> <script type="text/javascript" src="cordova.js"></script> <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> <script type="text/javascript"> //put JS code here </script> </body> </html>
Я добавил jQuery и jQuery Mobile из CDN. Вы можете встроить эти файлы локально, чтобы приложение работало без подключения к Интернету.
Инициализировать приложение
Когда приложение загружается, нам нужно создать объект базы данных и проверить, существует ли таблица для хранения данных или нет. Если таблица не существует, нам нужно ее создать.
Вот код для инициализации приложения. Поместите этот код в тег script
на странице index.html :
var db = null; document.addEventListener("deviceready", function(){ db = window.sqlitePlugin.openDatabase({name: "note.db"}); db.transaction(function(tx) { tx.executeSql("CREATE TABLE IF NOT EXISTS note (name text primary key, data text)"); }, function(err){ alert("An error occurred while initializing the app"); }); }, false);
Здесь мы создаем таблицу с двумя столбцами, именем и данными. Каждая заметка будет иметь уникальное имя для ее идентификации.
Создание главного экрана
Давайте создадим домашний экран, который будет отображаться при загрузке приложения. На домашнем экране появятся две кнопки для добавления и отображения заметок.
Поместите этот код в тег body
страницы index.html :
<div data-role="page" id="home"> <div data-role="header"> <h1>Home</h1> </div> <div data-role="main" class="ui-content"> <p> <a target="_blank" href="#add" style="text-decoration: none"><button>Add Note</button></a> <a target="_blank" href="#display" style="text-decoration: none"><button>Display Notes</button></a> </p> </div> </div>
Вот как выглядит страница:
Добавление заметки
Когда пользователь нажимает кнопку « Добавить заметку» , нам нужно отобразить еще одну страницу с двумя полями: поле для ввода имени заметки и другое для ввода данных заметки.
Поместите этот код в тег body
страницы index.html :
<div data-role="page" id="add"> <div data-role="header"> <a target="_blank" href="#home" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a> <h1>ADD</h1> </div> <div data-role="main" class="ui-content"> <input type="text" id="name" placeholder="Enter Name" /> <textarea id="note-text" placeholder="Place text here"></textarea> <a target="_blank" href="javascript:add()" style="text-decoration: none"><button>Add Note</button></a> </div> </div>
Когда пользователь нажимает кнопку « Добавить примечание» , вызывается функция add()
которая сохраняет данные в таблице.
Поместите этот код в тег script
на странице index.html :
function add() { var name = document.getElementById("name").value; var text = document.getElementById("note-text").value; if(name == "") { alert("Please enter name"); return; } if(text == "") { alert("Please enter text"); return; } db.transaction(function(tx) { tx.executeSql("INSERT INTO note (name, data) VALUES (?,?)", [name, text], function(tx,res){ alert("Note Added"); }); }, function(err){ alert("An error occured while saving the note"); }); }
Здесь мы проверяем, что поля ввода не пусты, а затем добавляем строку в таблицу.
Вот как выглядит страница:
Отображение списка заметок
На главной странице у нас есть кнопка с именем Показать заметки . Когда пользователь нажимает кнопку, нам нужно перейти на страницу, которая отображает все заметки.
Поместите этот код в тег body
страницы index.html :
<div data-role="page" id="display"> <div data-role="header"> <a target="_blank" href="#home" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a> <h1>NOTES</h1> </div> <div data-role="main" class="ui-content"> <ul id="data-list"> </ul> </div> </div>
Далее нам нужно извлечь все заметки из базы данных и заполнить эту страницу. Поместите этот код в тег script
на странице index.html :
$(document).on("pagebeforeshow", "#display", function(){ db.transaction(function(tx) { tx.executeSql("SELECT (name) FROM note", [], function(tx,res){ for(var iii = 0; iii < res.rows.length; iii++) { document.getElementById("data-list").innerHTML = document.getElementById("data-list").innerHTML + "<li><a href='javascript:displayNote(\"" + res.rows.item(iii).name + "\")'>" + res.rows.item(iii).name + "</a></li>"; } }); }, function(err){ alert("An error occured while displaying saved notes"); }); });
Мы возвращаем только столбец name
как это все, что мы отображаем. Затем мы заполняем область содержимого списком имен.
Вот как выглядит страница:
Отображение одной заметки
Когда пользователь нажимает на заметку в списке заметок, нам нужно отобразить полные данные заметки.
Для этого нам нужна еще одна страница. Поместите этот код в тег body
страницы index.html :
<div data-role="page" id="single-note"> <div data-role="header"> <a target="_blank" href="#display" class="ui-btn ui-icon-home ui-btn-icon-left">All</a> <h1 id="note-title"></h1> </div> <div data-role="main" class="ui-content"> <p id="note-data"></p> </div> </div>
Чтобы заполнить поля имени и данных, мы вызываем функцию, которая извлекает все данные о заметке из базы данных, когда пользователь нажимает на заметку.
Поместите этот код в тег script
на странице index.html :
function displayNote(name) { db.transaction(function(tx) { tx.executeSql("SELECT * FROM note WHERE name = ?", [name], function(tx,res){ var name = res.rows.item(0).name; var data = res.rows.item(0).data; document.getElementById("note-title").innerHTML = name; document.getElementById("note-data").innerHTML = data; $.mobile.changePage("#single-note"); }); }, function(err){ alert(err.message); alert("An error occured while displaying the note"); }); }
Вот как выглядит одна заметка:
Вывод
Приложение является функциональным и может быть развернуто на iOS, Android и Windows Phone, но является базовым. Следующие шаги по созданию полноценного приложения позволят пользователям редактировать и удалять заметки.
В этом руководстве демонстрируются плагин SQLite и веб-хранилище, но выбор механизма хранения для приложения является сложным решением. Какие еще варианты вы пробовали и как они у вас работали?