Разработка гибридных приложений для мобильных устройств под Windows Phone

Работа с локальными данными, хранящимися в памяти мобильного устройства

Разбить на страницы
Показывать лекцию целиком

Средства сохранения данных в памяти мобильного устройства. API Web Storage: медоды и свойства

При разработке гибридных приложений для мобильных устройств очень важную роль играет организация данных на их клиентской и серверной частях, обеспечение доступа к данным, а также организация обмена данными между клиентским приложением и сервером. Если разработка ведется на базе HTML5, то клиентская часть представляется приложением Cordova. Приложение Cordova - это .xap файл (по сути дела тот же zip архив, содержащий все ресурсы и сборки приложения). Серверная часть для мобильной платформы Windows Phone обычно представляется веб-приложением ASP.NET, которое обеспечивает доступ к данным большого объема.

В этой лекции мы рассмотрим средства хранения локальных данных на стороне клиента, непосредственно в памяти мобильного устройства (в .xap-файле Cardova - приложения) и возможности доступа к этим данным. Такие возможности появилась, прежде всего, благодаря новой спецификации HTML5 - API Web Storage (веб-хранилище) [1-3]. Ориентируясь на особенности мобильных устройств, появление облачных вычислений и необходимость стандартизировать технологии и инновации, внедряемые в течение многих лет посредством встраиваемых модулей, разработчики HTML5 объединили в этой спецификации всю функциональность, позволяющую выполнять полноценные клиентские приложения даже в отсутствие сетевого подключения. API Web Storage позволяет записывать данные в память мобильного устройства и обращаться к ним так же, как это делается в настольных приложениях. Процессы сохранения и извлечения данных, поддерживаемые этим API, применимы в двух ситуациях: когда информация должна быть доступна только в течение работы приложения и когда ее необходимо сохранить надолго - до тех пор, пока пользователь сам не удалит ее. Таким образом, для облегчения и упрощения жизни разработчиков этот API разделили на две части - sessionStorage и localstorage:

  • sessionStorage. Это механизм хранения, удерживающий данные только на протяжении работы приложения.
  • localStorage. Этот механизм работает аналогично системам хранения для настольных приложений. Данные записываются навсегда, и приложение, сохранившее их, может обращаться к этой информации в любой момент.
  • Оба механизма (соответствующую им память называют контейнерами localStorage и sessionStorage) работают через один и тот же интерфейс и предлагают одинаковые методы и свойства. Кроме того, оба механизма завязаны на источник, то есть любая информация в хранилище доступна только через приложение, которым она была создана. Рассмотрим спецификацию API sessionStorage и localStorage, позволяющую манипулировать данными:

  • setItem (ключ, значение) - этот метод добавляет в контейнер элемент данных с указанным ключом и значением. Элементы записываются в хранилище последовательно, и им автоматически присваиваются порядковые номера (числовые индексы), начиная с 0.
  • getItem (ключ) - метод возвращает из контейнера для хранения элемент данных, соответствующий указанному ключу.
  • key (индекс) - функция возвращает ключ элемента данных с указанным числовым индексом. С помощью данного метода можно извлечь определенный элемент или даже всю информацию, содержащуюся в хранилище, если пройтись по нему в цикле.
  • removeItem (ключ) - метод удаляет из контейнера для хранения элемент данных с указанным ключом. Для идентификации элемента методу нужно передать ключевое слово, которое использовалось в методе setItem() при создании элемента.
  • clear() - метод очищает текущий контейнер, то есть удаляет из него все данные.
  • length - свойство указывает, сколько элементов данных находится в контейнере. Оно работает точно так же, как обычное свойство length для массивов из JavaScript, и его удобно использовать для по-следовательного считывания элементов.
  • В этом API существует четкое разграничение временных и постоянных данных, благодаря чему становится намного проще конструировать как небольшие приложения, требующие временного хранения всего нескольких строк (например, содержимого корзины в интернет - магазине), так и объемные и сложные приложения, в которых нередко возникает необходимость сохранять на неопределенное время целые документы.

    В настоящее время в Cordova - приложениях выделяется для хранилищ до 5 Мбайт (данный размер обязательно будет расти по мере совершенствования мобильных устройств). Этого более чем достаточно для большинства создаваемых приложений. Однако будьте готовы к тому, что вам придется распознавать и обрабатывать ошибки, если вы будете пытаться записывать больше данных, чем позволяет ваше мобильное устройство.

    Контейнеры localStorage и sessionStorage реализованы по принципу синхронного выполнения, что упрощает их использование, однако может привести к снижению производительности. Будьте очень аккуратны, применяя данные из этих API в коде, где важны показатели производительности.

    Проверка памяти. Сохранение и извлечение данных по ключу

    Если нужно проверить, поддерживает ли мобильное устройство эти API, следует воспользоваться следующей командой JavaScript:

    if (window['localStorage'] !== null) ...

    Данные, сохраняемые в этих контейнерах, должны относиться к строковому типу. Если возникнет задача записать в хранилище сложные объекты, то одним из вариантов решения может стать их сериализация в JSON с помощью функции JSON.stringify().

    Для того, чтобы сохранить данные на время работы приложения, используется sessionStorage, например, такого содержания:

    var user_id = "A1B2C3D";
    var user_data = {
            vid: "Кошка", name: "Мурка", color: "Черная"
        };
        sessionStorage.setItem(user_id, JSON.stringify(user_data));

    Для извлечения данных из контейнера хранилища используется код, подобный этому:

    var user_id = " A1B2C3D";
        var user_data = {/*defaults */ };
        if (sessionStorage.getItem(user_id)) {
            user_data = JSON.parse(sessionStorage.getItem(user_id));
        };
        var rezult = user_data.vid + "  " + user_data.name + "  " + user_data.color;

    Примеры использования API в Cordova - приложениях

    Далее приводится первый пример страницы Cordova - приложения, содержащей обращения к трем JavaScript - функциям, использующим API для контейнера долговременного хранения localStorage. Назначение используемых в примере функций:

  • support_stor() - проверяет наличие контейнера в мобильном устройстве;
  • save_stor() - сохраняет в контейнере надолго одну запись;
  • load_stor() - читает запись из контейнера.
  • Разметка страницы включает подключение к содержащему используемые функции файлу "js/my_API.js":

    <!DOCTYPE html>
    <html lang="ru">
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, 
        minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <link rel="stylesheet" type="text/css" href="css/index.css" />
        <script type="text/javascript" src="js/my_API.js"></script>
        <title>Память</title>
        <style>
          h3 {font-family: Verdana, Arial, Helvetica, sans-serif;}
        </style>
        </head>
      <body>
        <h3>Работаем с локальной памятью мобильного устройства</h3><br />
           <input type ="button" id ="btn_sup" value="ПРОВЕРИТЬ ПАМЯТЬ" onclick = "support_stor();" /><br />
          <input type ="button" id ="btn_save" value="СОХРАНИТЬ    ПОЛЯ" onclick = "save_stor();" /><br />
          <input type ="button" id ="btn_load" value="ПРОЧИТАТЬ    ПОЛЯ" onclick = "load_stor();" /><br /><br />
          Результаты из локальной памяти:
        <br /><p id ="rezult">Здесь будет результат!</p>
      </body>
    </html>

    Содержимое подключаемого файла "js/my_API.js":

    function support_stor() {
        if (window['localStorage'] !== null)
        { document.getElementById("rezult").innerHTML = "Сохраню надолго!"; }
        else { document.getElementById("rezult").innerHTML = "НЕ сохраню!"; }
    };
    
    function save_stor() {
        var user_id = "1";
        var user_data = {
            vid: "Тигр", name: "Шархан", color: "Рыжий"
        };
        localStorage.setItem(user_id, JSON.stringify(user_data));
        document.getElementById("rezult").innerHTML = "Поля сохранены надолго!";
    };
    
    function load_stor() {
        var user_id = "1";
        var user_data = {/*defaults */ };
        if (localStorage.getItem(user_id)) {
            user_data = JSON.parse(localStorage.getItem(user_id));
        };
        document.getElementById("rezult").innerHTML = 
        user_data.vid + "  " + user_data.name + "  " + user_data.color;
    };

    Результаты тестирования данной программы, использующей спецификацию API localStorage:

    (рис 17.1)

    Второй пример, содержащий средства рассматриваемого API в Cordova - приложении. В нем также используется контейнер localStorage для сохранения данных (имя пользователя, его хобби, страна проживания). Но в отличие от первого примера, данные в нем вводятся с виртуальной клавиатуры мобильного устройства и путем установки значений в переключателях. Разметка страницы, содержащей тег <form> для общения с пользователем, имеет вид:

    <html lang="ru"><head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" type="text/css" href="css/my.css" />
     <script type="text/javascript" src="js/my_API.js"></script>
     <title>Долговременное хранение</title>
    </head>
    <body>
    <article>
    <header>
      <h3>Учет увлечений</h3>
    </header>
    <section>
      <form name="interest">
         Имя <input name=userName placeholder="Введите имя">
       <br>
        <div id="hobbyTable">
          <section id="getHobby">
            <fieldset>
              <legend>Любимое увлечение?</legend>
              <label>
     <input type=radio name=hobby  value="Чтение">
                Чтение</label>
              <br>
              <label>
    <input type=radio name=hobby value="Путешествия">
                Путешествия</label>           
              <br>
              <label>
                <input type=radio name=hobby value="Театр">
                Театр </label>
              <br>
              <label>
                <input type=radio name=hobby value="Балет">
                Балет</label>
              <br>
              <label>
                <input type=radio name=hobby value="Ралли внедорожников">
                Ралли внедорожников</label>
              <br>
            </fieldset>
          </section>
        </div><br>
          Страна проживания
        <br><input type=text name=resState placeholder="Страна проживания">
        <br>
        <input type=button onClick="StorageMaster.setRegistration()" value="Сохранить">
        <input type=button onClick="StorageMaster.getReg()" value="Найти"> <br>
        <input type=button onClick="StorageMaster.clearReg()" value="Очистить форму">
      </form>
    </section>
    <br>
    <pre id="profile"></pre>
        </article>
    </body>
    </html>

    Таблица стилей данной страницы (файл "css/my.css" ):

    body{
    	background-color:#F2EBC7;
    	color:#962D3E;
    	font-family:Verdana, Geneva, sans-serif;
        font-size:6px;
    }
    h3 {
    	color:#979C9C;
        font-size:8px;
    }
    fieldset {
    	color:#348899;
    }
    #hobbyTable {
    	display:table;
    }
    #getHobby {
    	display:table-cell;
    	width:155px;
    }
    #profile {
    	display:table-cell;
    	background-color: #979C9C;
    	padding: 3px;
    	width:150px;
    	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
    	font-size:24px;
    }

    Функции, добавленные в файл "js/my_API.js", содержащие методы объекта StorageMaster для работы с локальным контейнером:

    StorageMaster = new Object();
    //Сохраняем в контейнере данные формы interest
    StorageMaster.setRegistration = function () {
        this.hobbyNow = "";
        this.topCount = document.interest.elements.length;
        for (var count = 0; count < this.topCount; count++) {
            if (document.interest.elements[count].checked) {
                this.hobbyNow = document.interest.hobby[count - 2].value;
            }
        }
        localStorage.setItem("uName", document.interest.userName.value);
        localStorage.setItem("uHobby", this.hobbyNow);
        localStorage.setItem("uState", document.interest.resState.value);
    }
    //Получаем значения из контейнера
    StorageMaster.getReg = function () {
        userProfile = "Данные о пользователе:\n";
        nameNow = localStorage.getItem("uName") + "\n";
        hobbyNow = localStorage.getItem("uHobby") + "\n";
        stateNow = localStorage.getItem("uState") + "\n";
        fileLength = localStorage.length + " записи о пользователе";
        this.profile = userProfile + nameNow + hobbyNow + stateNow + fileLength;
        document.getElementById("profile").innerHTML = this.profile;
    }
    //Очищаем локальное хранилище
    StorageMaster.clearReg = function () {
        localStorage.clear();
        alert("Локальное хранилище очищено");
    }

    Одной из особенностей данного примера является использование переключателей для передачи данных на хранение. Переключатели играют важную роль в мобильных устройствах, упрощая задачу выбора пользователем нужных вариантов.

    Результат сохранения данных, выбранных и введенных пользователем во время работы Cordova - приложения (кадры соответствуют нажатиям на кнопки "Сохранить", "Найти", "Очистить форму"):

    (рис 17.2)

    Третий пример демонстрирует последовательную запись в долговременное хранилище набора элементов, вводимых пользователем, и извлечение элементов из хранилища путем прохода по данным хранилища в цикле. Содержание вводимых элементов произвольное, например, вот такое:

    Имя студентаЕго рост
    Валентин180
    Иван184
    Татьяна150
    Михаил175
    Виктор179

    Планируемый вид эмулятора мобильного устройства для данного примера (к сожалению, русификация не поддерживается):

    (рис 17.3)

    Для реализации этого примера достаточно одного HTML - документа, содержащего простую форму:

    <!DOCTYPE  html> 
    <html lang="ru"> 
    <head>
     <title>Веб-хранилище базы данных</title> 
     <link rel="stylesheet" href="css/storage.css"> 
     <script type="text/javascript" src="js/storage.js"></script>
    </head> 
    <body>
    <section id="formbox"> 
        <form name="form">
    <p>Ключевое слово (имя):</p>
        <p><input type="text" name="keyword" id="keyword"></p> 
        <p>Значение (рост,см):<br /><input type ="text" name="text" id="text" ></p>
    <p><input type ="button" id ="button" name ="button" value="СОХРАНИТЬ"/></p><br />
    </form> 
    <section id = "databox"> Информация недоступна </section> <br />
    </section> 
    </body> 
    </html>

    Подключаемый файл "css/storage.css" содержит простой набор правил для оформления страницы, благодаря которым поля для отображения данных будут визуально выделяться:

    #formbox{ float: left; 
              padding: 20px; 
              border: 1px solid #999999;
    } 
    #databox{
    float: left;
    width: 400px;
    margin-left: 20px;
    padding: 20px;
    border: 1px solid #999999;
    }
    #keyword, #text{
    width: 200px; }

    Приведенный далее JavaScript - код из файла "js/storage.js"использует методы key, setItem, getItem объекта localStorage, а также методы addEventListener для прослушивания двух событий - события click от объекта button (кнопка на форме) и события load (загрузка страницы) от объекта window:

    function initiate(){
        var button = document.getElementById('button');
        button.addEventListener('click', newitem, false);
        show();
        }
    function newitem(){
        var keyword=document.getElementById('keyword').value;
        var value = document.getElementById('text').value;
        localStorage.setItem(keyword,value);
        show();
        document.getElementById('keyword').value='';
        document.getElementById('text').value='';
    }
    function show() {
        var databox = document.getElementById('databox');
        databox.innerHTML += 'Содержание хранилища:';
        for (var f = 0; f < localStorage.length; f++) {
            var keyword = localStorage.key(f);
            var value = localStorage.getItem(keyword);
            databox.innerHTML += '<div>' + keyword + ' - ' + value + '</div>';
         }
    }
    window.addEventListener('load', initiate, false);

    В коде данного листинга функция newitem() выполняется каждый раз, когда пользователь щелкает на кнопке формы. Эта функция создает элемент и добавляет в него информацию, полученную из полей ввода формы, а затем вызывает функцию show(). Функция show(), в свою очередь, извлекает каждый элемент из хранилища по ключевому слову, используя метод getItem(keyword), а затем выводит его содержимое на экран мобильного устройства. Чтобы вывести полный список элементов из хранилища, в цикле for функции show() применяются свойство length и метод key(). Цикл for начинается с 0 и завершается порядковым номером последнего элемента из хранилища. Внутри цикла с помощью метода key() извлекается ключевое слово для каждой позиции. Например, если в позиции 0 пространства хранилища находится элемент с ключевым словом "Валентин", то код localStorage.key(0) возвращает значение "Валентин". Вызывая этот метод в цикле, мы проходим по всему списку и выводим на экран ключевые слова и значения всех элементов из хранилища. Функцию show() мы вызываем из функции initiate(). Таким образом, она выводит список элементов из хранилища на экран сразу же, как только запускается приложение:

    (рис 17.4)

    Удаление данных

    Элементы в хранилище можно создавать, считывать и, разумеется, удалять. Для выполнения последней задачи предназначены два метода - removeItem(key), который удаляет один элемент, и clear(), удаляющий все находящиеся в хранилище элементы. Чтобы реализовать удаление данных для приведенного выше третьего примера с именами и ростом студентов, в его JavaScript - коде немного изменим функцию show() и добавим две новые функции - remove() и removeAll(), которые соответственно удалят один элемент или выполнят полную очистку хранилища:

    function show() {
        var databox = document.getElementById('databox');
        databox.innerHTML = '<div><button onclick = "removeAll()"> 
    	Удалить Bce</button></div>';
        databox.innerHTML += 'Содержание хранилища:';
        for (var f = 0; f < localStorage.length; f++) {
            var keyword = localStorage.key(f);
            var value = localStorage.getItem(keyword);
            databox.innerHTML += '<div>' + keyword + ' - ' + value
             + '<BR><button onclick = "remove(\'' + keyword + '\') ">
     	Удaлить</button><br></div>';
        }
    }
    
    function remove(keyword){ 
        if(confirm('Вы уверены?')){
            localStorage.removeItem(keyword); show();
        }
    }
    function removeAll() {
        if (confirm('Вы уверены?')) {
            localStorage.clear(); show();
        }
    }

    Функции initiate() и newitem() в новой версии примера ничем не отличаются от аналогичных функций предыдущего примера кода. Изменилась только функция show(): теперь она включает в себя обработчики события onclick, которые вызывают функции, удаляющие отдельный элемент или все элементы хранилища соответственно. Список элементов строится точно так же, как раньше, но на этот раз к каждому элементу добавляется кнопка "Удалить". Кроме того, вверху списка создается еще одна кнопка, позволяющая полностью очистить хранилище. Скриншоты, приведенные далее, иллюстрируют процесс удаления одного элемента хранилища (ключ = "Vladimir").

    (рис 17.5)

    Используя код последнего примера данной лекции, можно протестировать обработку информации объектом sessionStorage. Для этого следует в JavaScript - коде всех функций заменить объект localStorage на sessionStorage. После выхода из приложения и повторного запуска содержимое экранов будет различаться: в случае localStorage сохранятся созданные вами элементы, а пространство хранилища для sessionStorage будет пустым. В отличие от других систем (таких, как файлы cookie), при использовании объекта sessionStorage хранимая информация никогда не выходит за пределы одного запуска приложения.

    Подробнее об API хранилищ HTML5 рассказывается на сайте [4].

    Страницы:

    Средства сохранения данных в памяти мобильного устройства. API Web Storage: медоды и свойства

    При разработке гибридных приложений для мобильных устройств очень важную роль играет организация данных на их клиентской и серверной частях, обеспечение доступа к данным, а также организация обмена данными между клиентским приложением и сервером. Если разработка ведется на базе HTML5, то клиентская часть представляется приложением Cordova. Приложение Cordova - это .xap файл (по сути дела тот же zip архив, содержащий все ресурсы и сборки приложения). Серверная часть для мобильной платформы Windows Phone обычно представляется веб-приложением ASP.NET, которое обеспечивает доступ к данным большого объема.

    В этой лекции мы рассмотрим средства хранения локальных данных на стороне клиента, непосредственно в памяти мобильного устройства (в .xap-файле Cardova - приложения) и возможности доступа к этим данным. Такие возможности появилась, прежде всего, благодаря новой спецификации HTML5 - API Web Storage (веб-хранилище) [1-3]. Ориентируясь на особенности мобильных устройств, появление облачных вычислений и необходимость стандартизировать технологии и инновации, внедряемые в течение многих лет посредством встраиваемых модулей, разработчики HTML5 объединили в этой спецификации всю функциональность, позволяющую выполнять полноценные клиентские приложения даже в отсутствие сетевого подключения. API Web Storage позволяет записывать данные в память мобильного устройства и обращаться к ним так же, как это делается в настольных приложениях. Процессы сохранения и извлечения данных, поддерживаемые этим API, применимы в двух ситуациях: когда информация должна быть доступна только в течение работы приложения и когда ее необходимо сохранить надолго - до тех пор, пока пользователь сам не удалит ее. Таким образом, для облегчения и упрощения жизни разработчиков этот API разделили на две части - sessionStorage и localstorage:

  • sessionStorage. Это механизм хранения, удерживающий данные только на протяжении работы приложения.
  • localStorage. Этот механизм работает аналогично системам хранения для настольных приложений. Данные записываются навсегда, и приложение, сохранившее их, может обращаться к этой информации в любой момент.
  • Оба механизма (соответствующую им память называют контейнерами localStorage и sessionStorage) работают через один и тот же интерфейс и предлагают одинаковые методы и свойства. Кроме того, оба механизма завязаны на источник, то есть любая информация в хранилище доступна только через приложение, которым она была создана. Рассмотрим спецификацию API sessionStorage и localStorage, позволяющую манипулировать данными:

  • setItem (ключ, значение) - этот метод добавляет в контейнер элемент данных с указанным ключом и значением. Элементы записываются в хранилище последовательно, и им автоматически присваиваются порядковые номера (числовые индексы), начиная с 0.
  • getItem (ключ) - метод возвращает из контейнера для хранения элемент данных, соответствующий указанному ключу.
  • key (индекс) - функция возвращает ключ элемента данных с указанным числовым индексом. С помощью данного метода можно извлечь определенный элемент или даже всю информацию, содержащуюся в хранилище, если пройтись по нему в цикле.
  • removeItem (ключ) - метод удаляет из контейнера для хранения элемент данных с указанным ключом. Для идентификации элемента методу нужно передать ключевое слово, которое использовалось в методе setItem() при создании элемента.
  • clear() - метод очищает текущий контейнер, то есть удаляет из него все данные.
  • length - свойство указывает, сколько элементов данных находится в контейнере. Оно работает точно так же, как обычное свойство length для массивов из JavaScript, и его удобно использовать для по-следовательного считывания элементов.
  • В этом API существует четкое разграничение временных и постоянных данных, благодаря чему становится намного проще конструировать как небольшие приложения, требующие временного хранения всего нескольких строк (например, содержимого корзины в интернет - магазине), так и объемные и сложные приложения, в которых нередко возникает необходимость сохранять на неопределенное время целые документы.

    В настоящее время в Cordova - приложениях выделяется для хранилищ до 5 Мбайт (данный размер обязательно будет расти по мере совершенствования мобильных устройств). Этого более чем достаточно для большинства создаваемых приложений. Однако будьте готовы к тому, что вам придется распознавать и обрабатывать ошибки, если вы будете пытаться записывать больше данных, чем позволяет ваше мобильное устройство.

    Контейнеры localStorage и sessionStorage реализованы по принципу синхронного выполнения, что упрощает их использование, однако может привести к снижению производительности. Будьте очень аккуратны, применяя данные из этих API в коде, где важны показатели производительности.

    Проверка памяти. Сохранение и извлечение данных по ключу

    Если нужно проверить, поддерживает ли мобильное устройство эти API, следует воспользоваться следующей командой JavaScript:

    if (window['localStorage'] !== null) ...

    Данные, сохраняемые в этих контейнерах, должны относиться к строковому типу. Если возникнет задача записать в хранилище сложные объекты, то одним из вариантов решения может стать их сериализация в JSON с помощью функции JSON.stringify().

    Для того, чтобы сохранить данные на время работы приложения, используется sessionStorage, например, такого содержания:

    var user_id = "A1B2C3D";
    var user_data = {
            vid: "Кошка", name: "Мурка", color: "Черная"
        };
        sessionStorage.setItem(user_id, JSON.stringify(user_data));

    Для извлечения данных из контейнера хранилища используется код, подобный этому:

    var user_id = " A1B2C3D";
        var user_data = {/*defaults */ };
        if (sessionStorage.getItem(user_id)) {
            user_data = JSON.parse(sessionStorage.getItem(user_id));
        };
        var rezult = user_data.vid + "  " + user_data.name + "  " + user_data.color;

    Примеры использования API в Cordova - приложениях

    Далее приводится первый пример страницы Cordova - приложения, содержащей обращения к трем JavaScript - функциям, использующим API для контейнера долговременного хранения localStorage. Назначение используемых в примере функций:

  • support_stor() - проверяет наличие контейнера в мобильном устройстве;
  • save_stor() - сохраняет в контейнере надолго одну запись;
  • load_stor() - читает запись из контейнера.
  • Разметка страницы включает подключение к содержащему используемые функции файлу "js/my_API.js":

    <!DOCTYPE html>
    <html lang="ru">
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, 
        minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <link rel="stylesheet" type="text/css" href="css/index.css" />
        <script type="text/javascript" src="js/my_API.js"></script>
        <title>Память</title>
        <style>
          h3 {font-family: Verdana, Arial, Helvetica, sans-serif;}
        </style>
        </head>
      <body>
        <h3>Работаем с локальной памятью мобильного устройства</h3><br />
           <input type ="button" id ="btn_sup" value="ПРОВЕРИТЬ ПАМЯТЬ" onclick = "support_stor();" /><br />
          <input type ="button" id ="btn_save" value="СОХРАНИТЬ    ПОЛЯ" onclick = "save_stor();" /><br />
          <input type ="button" id ="btn_load" value="ПРОЧИТАТЬ    ПОЛЯ" onclick = "load_stor();" /><br /><br />
          Результаты из локальной памяти:
        <br /><p id ="rezult">Здесь будет результат!</p>
      </body>
    </html>

    Содержимое подключаемого файла "js/my_API.js":

    function support_stor() {
        if (window['localStorage'] !== null)
        { document.getElementById("rezult").innerHTML = "Сохраню надолго!"; }
        else { document.getElementById("rezult").innerHTML = "НЕ сохраню!"; }
    };
    
    function save_stor() {
        var user_id = "1";
        var user_data = {
            vid: "Тигр", name: "Шархан", color: "Рыжий"
        };
        localStorage.setItem(user_id, JSON.stringify(user_data));
        document.getElementById("rezult").innerHTML = "Поля сохранены надолго!";
    };
    
    function load_stor() {
        var user_id = "1";
        var user_data = {/*defaults */ };
        if (localStorage.getItem(user_id)) {
            user_data = JSON.parse(localStorage.getItem(user_id));
        };
        document.getElementById("rezult").innerHTML = 
        user_data.vid + "  " + user_data.name + "  " + user_data.color;
    };

    Результаты тестирования данной программы, использующей спецификацию API localStorage:

    (рис 17.1)

    Второй пример, содержащий средства рассматриваемого API в Cordova - приложении. В нем также используется контейнер localStorage для сохранения данных (имя пользователя, его хобби, страна проживания). Но в отличие от первого примера, данные в нем вводятся с виртуальной клавиатуры мобильного устройства и путем установки значений в переключателях. Разметка страницы, содержащей тег <form> для общения с пользователем, имеет вид:

    <html lang="ru"><head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" type="text/css" href="css/my.css" />
     <script type="text/javascript" src="js/my_API.js"></script>
     <title>Долговременное хранение</title>
    </head>
    <body>
    <article>
    <header>
      <h3>Учет увлечений</h3>
    </header>
    <section>
      <form name="interest">
         Имя <input name=userName placeholder="Введите имя">
       <br>
        <div id="hobbyTable">
          <section id="getHobby">
            <fieldset>
              <legend>Любимое увлечение?</legend>
              <label>
     <input type=radio name=hobby  value="Чтение">
                Чтение</label>
              <br>
              <label>
    <input type=radio name=hobby value="Путешествия">
                Путешествия</label>           
              <br>
              <label>
                <input type=radio name=hobby value="Театр">
                Театр </label>
              <br>
              <label>
                <input type=radio name=hobby value="Балет">
                Балет</label>
              <br>
              <label>
                <input type=radio name=hobby value="Ралли внедорожников">
                Ралли внедорожников</label>
              <br>
            </fieldset>
          </section>
        </div><br>
          Страна проживания
        <br><input type=text name=resState placeholder="Страна проживания">
        <br>
        <input type=button onClick="StorageMaster.setRegistration()" value="Сохранить">
        <input type=button onClick="StorageMaster.getReg()" value="Найти"> <br>
        <input type=button onClick="StorageMaster.clearReg()" value="Очистить форму">
      </form>
    </section>
    <br>
    <pre id="profile"></pre>
        </article>
    </body>
    </html>

    Таблица стилей данной страницы (файл "css/my.css" ):

    body{
    	background-color:#F2EBC7;
    	color:#962D3E;
    	font-family:Verdana, Geneva, sans-serif;
        font-size:6px;
    }
    h3 {
    	color:#979C9C;
        font-size:8px;
    }
    fieldset {
    	color:#348899;
    }
    #hobbyTable {
    	display:table;
    }
    #getHobby {
    	display:table-cell;
    	width:155px;
    }
    #profile {
    	display:table-cell;
    	background-color: #979C9C;
    	padding: 3px;
    	width:150px;
    	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
    	font-size:24px;
    }

    Функции, добавленные в файл "js/my_API.js", содержащие методы объекта StorageMaster для работы с локальным контейнером:

    StorageMaster = new Object();
    //Сохраняем в контейнере данные формы interest
    StorageMaster.setRegistration = function () {
        this.hobbyNow = "";
        this.topCount = document.interest.elements.length;
        for (var count = 0; count < this.topCount; count++) {
            if (document.interest.elements[count].checked) {
                this.hobbyNow = document.interest.hobby[count - 2].value;
            }
        }
        localStorage.setItem("uName", document.interest.userName.value);
        localStorage.setItem("uHobby", this.hobbyNow);
        localStorage.setItem("uState", document.interest.resState.value);
    }
    //Получаем значения из контейнера
    StorageMaster.getReg = function () {
        userProfile = "Данные о пользователе:\n";
        nameNow = localStorage.getItem("uName") + "\n";
        hobbyNow = localStorage.getItem("uHobby") + "\n";
        stateNow = localStorage.getItem("uState") + "\n";
        fileLength = localStorage.length + " записи о пользователе";
        this.profile = userProfile + nameNow + hobbyNow + stateNow + fileLength;
        document.getElementById("profile").innerHTML = this.profile;
    }
    //Очищаем локальное хранилище
    StorageMaster.clearReg = function () {
        localStorage.clear();
        alert("Локальное хранилище очищено");
    }

    Одной из особенностей данного примера является использование переключателей для передачи данных на хранение. Переключатели играют важную роль в мобильных устройствах, упрощая задачу выбора пользователем нужных вариантов.

    Результат сохранения данных, выбранных и введенных пользователем во время работы Cordova - приложения (кадры соответствуют нажатиям на кнопки "Сохранить", "Найти", "Очистить форму"):

    (рис 17.2)

    Третий пример демонстрирует последовательную запись в долговременное хранилище набора элементов, вводимых пользователем, и извлечение элементов из хранилища путем прохода по данным хранилища в цикле. Содержание вводимых элементов произвольное, например, вот такое:

    Имя студентаЕго рост
    Валентин180
    Иван184
    Татьяна150
    Михаил175
    Виктор179

    Планируемый вид эмулятора мобильного устройства для данного примера (к сожалению, русификация не поддерживается):

    (рис 17.3)

    Для реализации этого примера достаточно одного HTML - документа, содержащего простую форму:

    <!DOCTYPE  html> 
    <html lang="ru"> 
    <head>
     <title>Веб-хранилище базы данных</title> 
     <link rel="stylesheet" href="css/storage.css"> 
     <script type="text/javascript" src="js/storage.js"></script>
    </head> 
    <body>
    <section id="formbox"> 
        <form name="form">
    <p>Ключевое слово (имя):</p>
        <p><input type="text" name="keyword" id="keyword"></p> 
        <p>Значение (рост,см):<br /><input type ="text" name="text" id="text" ></p>
    <p><input type ="button" id ="button" name ="button" value="СОХРАНИТЬ"/></p><br />
    </form> 
    <section id = "databox"> Информация недоступна </section> <br />
    </section> 
    </body> 
    </html>

    Подключаемый файл "css/storage.css" содержит простой набор правил для оформления страницы, благодаря которым поля для отображения данных будут визуально выделяться:

    #formbox{ float: left; 
              padding: 20px; 
              border: 1px solid #999999;
    } 
    #databox{
    float: left;
    width: 400px;
    margin-left: 20px;
    padding: 20px;
    border: 1px solid #999999;
    }
    #keyword, #text{
    width: 200px; }

    Приведенный далее JavaScript - код из файла "js/storage.js"использует методы key, setItem, getItem объекта localStorage, а также методы addEventListener для прослушивания двух событий - события click от объекта button (кнопка на форме) и события load (загрузка страницы) от объекта window:

    function initiate(){
        var button = document.getElementById('button');
        button.addEventListener('click', newitem, false);
        show();
        }
    function newitem(){
        var keyword=document.getElementById('keyword').value;
        var value = document.getElementById('text').value;
        localStorage.setItem(keyword,value);
        show();
        document.getElementById('keyword').value='';
        document.getElementById('text').value='';
    }
    function show() {
        var databox = document.getElementById('databox');
        databox.innerHTML += 'Содержание хранилища:';
        for (var f = 0; f < localStorage.length; f++) {
            var keyword = localStorage.key(f);
            var value = localStorage.getItem(keyword);
            databox.innerHTML += '<div>' + keyword + ' - ' + value + '</div>';
         }
    }
    window.addEventListener('load', initiate, false);

    В коде данного листинга функция newitem() выполняется каждый раз, когда пользователь щелкает на кнопке формы. Эта функция создает элемент и добавляет в него информацию, полученную из полей ввода формы, а затем вызывает функцию show(). Функция show(), в свою очередь, извлекает каждый элемент из хранилища по ключевому слову, используя метод getItem(keyword), а затем выводит его содержимое на экран мобильного устройства. Чтобы вывести полный список элементов из хранилища, в цикле for функции show() применяются свойство length и метод key(). Цикл for начинается с 0 и завершается порядковым номером последнего элемента из хранилища. Внутри цикла с помощью метода key() извлекается ключевое слово для каждой позиции. Например, если в позиции 0 пространства хранилища находится элемент с ключевым словом "Валентин", то код localStorage.key(0) возвращает значение "Валентин". Вызывая этот метод в цикле, мы проходим по всему списку и выводим на экран ключевые слова и значения всех элементов из хранилища. Функцию show() мы вызываем из функции initiate(). Таким образом, она выводит список элементов из хранилища на экран сразу же, как только запускается приложение:

    (рис 17.4)

    Удаление данных

    Элементы в хранилище можно создавать, считывать и, разумеется, удалять. Для выполнения последней задачи предназначены два метода - removeItem(key), который удаляет один элемент, и clear(), удаляющий все находящиеся в хранилище элементы. Чтобы реализовать удаление данных для приведенного выше третьего примера с именами и ростом студентов, в его JavaScript - коде немного изменим функцию show() и добавим две новые функции - remove() и removeAll(), которые соответственно удалят один элемент или выполнят полную очистку хранилища:

    function show() {
        var databox = document.getElementById('databox');
        databox.innerHTML = '<div><button onclick = "removeAll()"> 
    	Удалить Bce</button></div>';
        databox.innerHTML += 'Содержание хранилища:';
        for (var f = 0; f < localStorage.length; f++) {
            var keyword = localStorage.key(f);
            var value = localStorage.getItem(keyword);
            databox.innerHTML += '<div>' + keyword + ' - ' + value
             + '<BR><button onclick = "remove(\'' + keyword + '\') ">
     	Удaлить</button><br></div>';
        }
    }
    
    function remove(keyword){ 
        if(confirm('Вы уверены?')){
            localStorage.removeItem(keyword); show();
        }
    }
    function removeAll() {
        if (confirm('Вы уверены?')) {
            localStorage.clear(); show();
        }
    }

    Функции initiate() и newitem() в новой версии примера ничем не отличаются от аналогичных функций предыдущего примера кода. Изменилась только функция show(): теперь она включает в себя обработчики события onclick, которые вызывают функции, удаляющие отдельный элемент или все элементы хранилища соответственно. Список элементов строится точно так же, как раньше, но на этот раз к каждому элементу добавляется кнопка "Удалить". Кроме того, вверху списка создается еще одна кнопка, позволяющая полностью очистить хранилище. Скриншоты, приведенные далее, иллюстрируют процесс удаления одного элемента хранилища (ключ = "Vladimir").

    (рис 17.5)

    Используя код последнего примера данной лекции, можно протестировать обработку информации объектом sessionStorage. Для этого следует в JavaScript - коде всех функций заменить объект localStorage на sessionStorage. После выхода из приложения и повторного запуска содержимое экранов будет различаться: в случае localStorage сохранятся созданные вами элементы, а пространство хранилища для sessionStorage будет пустым. В отличие от других систем (таких, как файлы cookie), при использовании объекта sessionStorage хранимая информация никогда не выходит за пределы одного запуска приложения.

    Подробнее об API хранилищ HTML5 рассказывается на сайте [4].

    Вернуться к учебному плану