Доступ к базам данных – очень востребованный функционал приложений. И в этот раз мы рассмотрим способ для 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');
}
И вот, после запуска увидим такое:

На этом все.
Скачать исходный код демонстрационного приложения.