Доступ к базам данных – очень востребованный функционал приложений. И в этот раз мы рассмотрим способ для WebOS приложений получить данные из базы данных MySQL, находящейся на удаленном сервере.
Для начала создадим новое приложение и в нем новую сцену с названием Main. Как создать проект и сцену можно узнать из этой статьи.
Затем добавим в созданную сцену список:
views/main/main-scene.html
<div class="palm-group"> <div class="palm-group-title" id="sample-toggle"> <span x-mojo-loc="">Database Content</span></div> <div class="palm-list"> <div id="dbList" x-mojo-element='List'></div> </div> </div> </div>
Для нашего списка нам необходимо определить HTML-шаблон элементов списка:
views/main/dbItemTemplate.html
<div class="palm-row" x-mojo-tap-highlight="momentary"> <div id="nameField">#{Name} (#{Year})</div> </div>
В шаблоне указано, что если в элементе списка есть свойства Name и Year, то они должны быть отображены.
Теперь в assistants/main-assistant.js внесем необходимые изменения для того, чтобы виджет-список создался при запуске:
function MainAssistant() { } MainAssistant.prototype.setup = function() { this.count = 0; this.dbListModel = {}; this.controller.setupWidget("dbList", { itemTemplate: "main/dbItemTemplate" }, this.dbListModel); }
Как видно из кода, в атрибутах виджета мы указываем шаблон элементов main/dbItemTemplate. Название должно совпадать с названием ранее созданного HTML-файла с описанием шаблона элементов.
После всех манипуляций, описанных выше, у нас должно получиться что-то подобное:
Отлично, с GUI мы закончили, теперь займемся получением данных с сервера.
Для начала создадим базу данных и в ней таблицу, из которой мы будем получать записи и отображать их на форме:
CREATE TABLE remote_data( ID INTEGER NOT NULL AUTO_INCREMENT , Name VARCHAR( 32 ) NOT NULL , Year SMALLINT NOT NULL , PRIMARY KEY ( ID ) );
Затем создадим PHP-скрипт, который будет получать данные из таблицы и выдавать их в формате JSON:
<?php header('Content-type: application/json'); $dbhost = "localhost"; $dbuser = "root"; $dbpass = ""; $dbname = "webos_test"; $link = mysql_connect($dbhost, $dbuser, $dbpass) or die('Could not connect: ' . mysql_error()); mysql_select_db($dbname) or die('Could not select database'); switch($_POST['operation']) { case 'getResults': { $table = $_POST['table']; $query = sprintf("SELECT * FROM %s", mysql_real_escape_string($table)); $result = mysql_query($query) or die('Query failed: ' . mysql_error()); $all_recs = array(); while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { $all_recs[] = $line; } break; } } echo json_encode($all_recs); mysql_free_result($result); mysql_close($link); ?>
Что делает этот скрипт:
- Получает из POST-параметров название операции, непример getResults.
- Если операция поддерживается, то получает из POST-параметров имя таблицы
- Получает записи из таблицы в массив
- Конвертирует в JSON и отдает клиенту
В результате у нас в выдаче должно получиться что-то подобное:
[ {"ID":"1","Name":"Test 1","Year":"2008"}, {"ID":"2","Name":"Test 2","Year":"2009"}, {"ID":"3","Name":"Test 3","Year":"2010"} ]
Теперь нам надо научить наше WebOS приложение получать эти данные с сервера.
Для получения данных в приложении нам необходимо выполнить AJAX-запрос на сервер. Для этого используется метода Ajax.Request():
MainAssistant.prototype.getRemoteData = function(table) { var url = 'http://192.168.0.1/remote-data.php'; try { if(!table) { throw('getRemoteData(): You should specify database table name'); } var request = new Ajax.Request(url, { method: 'post', parameters: {'operation': 'getResults', 'table': table}, evalJSON: 'true', onSuccess: this.getRemoteDataSuccess.bind(this), onFailure: function() { Mojo.Log.error('Failed to get Ajax response'); } }); } catch(e) { Mojo.log.error(e); } }
В исходном коде указан IP адрес машины в локальной сети. Если вы тестируете приложение на эмуляторе, а сервер со скриптом и базой данных находится в Internet, то, скорее всего, доступа к серверу у вас по умолчанию не будет. Для того, чтобы разрешить эмулятору ходить в сеть, надо в настройках LAN-соединения разрешить доступ из подсети VirtualBox:
Итак, в приведенном выше коде указано, что при успешном завершении запроса необходимо вызвать метод getRemoteDataSuccess(). В этом методе мы должны преобразовать полученный ответ от сервера в массив и обновить список. Делается это следующим образом:
MainAssistant.prototype.getRemoteDataSuccess = function(response) { try { this.dbListModel.items = response.responseText.evalJSON(); this.controller.modelChanged(this.dbListModel); } catch(e) { Mojo.log.error(e); } }
Для преобразования JSON-строки в массив мы использовали метод evalJSON(), а для того чтобы виджет обновил список элементов мы вызвали метод modelChanged() объекта-контроллера.
Все это чудесно, научили приложение делать запрос к серверу и обрабатывать результаты, но если мы запустим приложение, то ничего не произойдет. А все потому что мы не указали, когда должен вызываться метод getRemoteData().
Вызвать этот метод можно при запуске приложения. У класса сцены есть метод, который отрабатывает, когда сцена загружена. Это метод ready(). Вот в нем мы и запустим выполнение AJAX-запроса:
MainAssistant.prototype.ready = function() { this.getRemoteData('remote_data'); }
И вот, после запуска увидим такое:
На этом все.