Статьи

Titanium Mobile: Таблицы на основе баз данных с SQLite — Часть 2

Добро пожаловать во вторую часть нашей серии, посвященной разработке Titanium Mobile для управления базами данных. В этом руководстве мы будем вставлять значения в локальную базу данных SQLite, а также читать и записывать данные в удаленную базу данных MySQL. В этом уроке будет много кода, но я постарался быть максимально тщательным, никому не надоедая. Принесите свои вопросы в разделы комментариев!


В первой части этой серии мы создали локальную базу данных SQLite и создали только три файла, которые генерировали страницы с отдельными спецификациями для каждой записи. Используя этот метод, наше приложение становится проще в управлении и занимает меньше места. Мы будем использовать большую часть кода с первого раза.

ПРИМЕЧАНИЕ: я изменил две вещи в источнике из предыдущего тут. Одно было неверное имя базы данных, а другое — имя переменной, что вызвало некоторую путаницу. Пожалуйста, скачайте исходный код, чтобы избежать головной боли.


Откройте Titanium Developer и создайте новый проект. Выберите Мобильный и заполните всю необходимую информацию. Затем нажмите Создать проект . Скопируйте папку «products» и базу данных «products.sqlite» в новый каталог ресурсов. Эти файлы не нужно трогать. Теперь мы готовы к работе.


Нам понадобятся четыре вкладки для этого. Мне нравится использовать файл app.js только в качестве шлюза к приложению. Лично я чувствую, что так все проще организовать. Мы собираемся создать вкладки и открыть им новые файлы. Вот окончательный код для app.js. Это довольно просто и линейно.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
var tabGroup = Ti.UI.createTabGroup();
 
var win1 = Ti.UI.createWindow({
    title:’Local Read’,
    url:’products/product_category.js’
});
 
var tab1 = Ti.UI.createTab({
    icon:’images/tabs/KS_nav_ui.png’,
    title:’Local Read’,
    window:win1
});
 
var win2 = Ti.UI.createWindow({
    title:’Local Insert’,
    url:’products/products_write.js’
});
 
var tab2 = Ti.UI.createTab({
    icon:’images/tabs/KS_nav_ui.png’,
    title:’Local Insert’,
    window:win2
});
 
var win3 = Ti.UI.createWindow({
    title:’Remote Read’,
    url:’remote_read.js’
});
 
var tab3 = Ti.UI.createTab({
    icon:’images/tabs/KS_nav_ui.png’,
    title:’Remote Read’,
    window:win3
});
 
var win4 = Ti.UI.createWindow({
    title:’Remote Insert’,
    url:’remote_write.js’
});
 
var tab4 = Ti.UI.createTab({
    icon:’images/tabs/KS_nav_ui.png’,
    title:’Remote Insert’,
    window:win4
});
 
tabGroup.addTab(tab1);
tabGroup.addTab(tab2);
tabGroup.addTab(tab3);
tabGroup.addTab(tab4);
 
tabGroup.open();

Вкладка 1 — это весь предыдущий текст. Мы не будем трогать эти файлы, а продолжим и создадим файлы-заполнители для остальных трех вкладок.


Локальная база данных перед вставкой

Откройте файл «products_write.js». В этом файле нам нужно будет создать текстовое поле для каждого поля в нашей базе данных, создать кнопку и прикрепить к ней eventListener, чтобы выполнить некоторую проверку и выполнить функцию, а также создать функцию для вставки данных. Много повторного кода. Вот конечный продукт:

Вкладка «Локальная база данных»

Сокращенный код будет выглядеть следующим образом. Все текстовые поля имеют одинаковые атрибуты, за исключением переменных «top» и «hintText». Мы будем смотреть только на одного.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// create var for the currentWindow
var currentWin = Ti.UI.currentWindow;
 
function insertRows(dbData) {
    **FUNCTION HERE**
};
 
var category = Ti.UI.createTextField({
    color:’#336699′,
    top:10,
    left:10,
    width:300,
    height:40,
    hintText:’Category’,
    keyboardType:Ti.UI.KEYBOARD_DEFAULT,
    borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED
});
 
currentWin.add(category);
 
var name = Ti.UI.createTextField({
    …
});
 
currentWin.add(name);
 
var pwidth = Ti.UI.createTextField({
    …
});
 
currentWin.add(pwidth);
 
var pheight = Ti.UI.createTextField({
    …
});
 
currentWin.add(pheight);
 
var pcolor = Ti.UI.createTextField({
    …
});
 
currentWin.add(pcolor);
 
var qty = Ti.UI.createTextField({
    …
});
 
currentWin.add(qty);
 
var btn = Ti.UI.createButton({
    title:’Insert Record’,
    top:310,
    width:130,
    height:35,
    borderRadius:1,
    font:{fontFamily:’Arial’,fontWeight:’bold’,fontSize:14}
});
 
currentWin.add(btn);
 
btn.addEventListener(‘click’,function(e) {
    if (category.value != » && name.value != » && pwidth.value != » && pheight.value != » && pcolor.value != » && qty.value != ») {
        var dbData = {
            category: category.value,
            name: name.value,
            pwidth: pwidth.value,
            pheight: pheight.value,
            pcolor: pcolor.value,
            qty: qty.value
        };
        insertRows(dbData);
    } else {
        alert(«Please fill in all fields»);
    };
});

Текстовые поля созданы и атрибуты назначены. Имя переменной — это то, что мы будем использовать позже. Кнопка создается, а затем мы добавляем eventListener. Здесь мы сначала проверяем, что текстовые поля не равны (! =) «Blank», а затем создаем переменную со значениями текстового поля. Эти значения затем передаются в функцию insertRows (). Если поле оставить пустым, активируется оповещение.

Оповещение о вставке локальной базы данных

Функция получает значения текстового поля из dbData. Затем мы создаем наш оператор SQL, используем наши db var и «execute» для создания другого var, вызываем этот var и, наконец, предупреждаем, что строки были вставлены. Если при вставке произошла ошибка, это предупреждение не сработает. Вероятно, случится так, что приложение потерпит крах.

01
02
03
04
05
06
07
08
09
10
11
function insertRows(dbData) {
 
    var db = Ti.Database.install(‘../products.sqlite’,’products’);
 
    var theData = db.execute(‘INSERT INTO products (category, name, pwidth, pheight, pcolor, qty) VALUES(«‘+category.value+'»,»‘+name.value+'», «‘+pwidth.value+'», «‘+pheight.value+'», «‘+pcolor.value+'», «‘+qty.value+'»)’);
 
    theData;
     
    alert(«Rows Inserted»);
     
};
Локальная база данных, прочитанная после вставки

Вот наша теперь обновленная локальная база данных. Примечание: у меня нет объяснения этому, но симулятор iOS не будет показывать обновления вашей базы данных, пока вы не выйдете и не перезапустите. Это относится к локальным и удаленным базам данных.


Удаленные базы данных не могут быть вызваны напрямую из приложения. Нам нужно использовать Ti.Network.createHTTPClient (); чтобы открыть файл PHP, который будет подключаться к нашей базе данных, запросить его и вернуть значения в приложение. Мы сделаем это с помощью JSON.

Сначала нам нужно создать нашу удаленную базу данных. Для удобства я экспортировал свою базу данных. Вы можете использовать phpMyAdmin для его импорта. Мы собираемся работать с сервера на приложение.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
$mysqli = new mysqli(«localhost»,»your_user_name»,»your_pass_word»,»your_table_name»);
if (mysqli_connect_errno()) {
    printf(«Can’t connect to SQL Server. Error Code %s\n», mysqli_connect_error($mysqli));
    exit;
}
// Set the default namespace to utf8
$mysqli->query(«SET NAMES ‘utf8′»);
$json = array();
if($result = $mysqli->query(«select * from colors»)) {
    while ($row=$result->fetch_assoc()) {
        $json[]=array(
            ‘shade’=>$row[‘shade’],
        );
    }
}
$result->close();
 
header(«Content-Type: text/json»);
echo json_encode(array( ‘colors’ => $json ));
 
$mysqli->close();
?>

Если вы много работаете с PHP и MySQL, это должно выглядеть довольно знакомо. Мы используем mysqli (улучшенную версию драйвера MySQL от PHP) для создания соединения с нашей базой данных, возврата ошибки, если она не соединяется, создания нашего массива и возврата его в наше приложение. Единственное, на что я действительно хочу обратить внимание, это в отношении заполнения массива. Я сохранил это очень просто ради времени. Если вы хотите передать больше значений, просто добавьте запрос, а затем добавьте значения в массив.

Файл приложения также прост. Мы создаем нашу переменную с помощью Ti.Network.createHTTPClient (), устанавливаем URL-адрес «open» для файла PHP, отправляем запрос, а затем получаем его и анализируем ответ. Мы используем тот же метод, который мы использовали с первого раза, чтобы сгенерировать массив здесь, но используем .push.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var currentWin = Ti.UI.currentWindow;
 
var sendit = Ti.Network.createHTTPClient();
sendit.open(‘GET’, ‘http://www.danstever.com/sandbox/mobile_tuts/read.php’);
sendit.send();
sendit.onload = function(){
    var json = JSON.parse(this.responseText);
 
    var json = json.colors;
 
    var dataArray = [];
 
    var pos;
    for( pos=0; pos < json.length; pos++){
 
        dataArray.push({title:» + json[pos].shade + »});
        // set the array to the tableView
        tableview.setData(dataArray);
    };
 
};
 
var tableview = Ti.UI.createTableView({
});
 
currentWin.add(tableview);

Теперь вы сможете просматривать онлайн-базу данных:

Вкладка «Удаленное чтение базы данных»

Файл локального приложения для удаленной вставки почти такой же, как указано выше. Есть два отличия: мы используем файл PHP и Ti.Network и должны отлавливать любые ошибки или предупреждения из файла PHP. Вот вкладка вставки:

Вкладка «Удаленная база данных»
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
var currentWin = Ti.UI.currentWindow;
 
var shade = Ti.UI.createTextField({
    color:’#336699′,
    top:70,
    left:10,
    width:300,
    height:40,
    hintText:’Color’,
    keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
    borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
 
currentWin.add(shade);
 
var btn = Ti.UI.createButton({
    title:’Insert Record’,
    top:130,
    width:130,
    height:35,
    borderRadius:1,
    font:{fontFamily:’Arial’,fontWeight:’bold’,fontSize:14}
});
currentWin.add(btn);
 
 
var request = Ti.Network.createHTTPClient();
request.onload = function()
{
    if (this.responseText == «Insert failed»)
    {
        btn.enabled = true;
        btn.opacity = 1;
        alert(this.responseText);
    }
    else
    {
        var alertDialog = Ti.UI.createAlertDialog({
            title: ‘Alert’,
            message: this.responseText,
            buttonNames: [‘OK’]
        });
        alertDialog.show();
        alertDialog.addEventListener(‘click’,function(e)
        {
            currentWin.tabGroup.setActiveTab(2);
        });
    }
};
 
btn.addEventListener(‘click’,function(e)
{
    if (shade.value != »){
 
        request.open(«POST»,»http://danstever.com/sandbox/mobile_tuts/insert.php»);
            var params = {
                shade: shade.value
            };
            request.send(params);
    } else {
            alert(«Please enter a color.»);
    };
});

Функция onload прослушивает ответы со страницы PHP. Если есть ошибка, это заставит приложение выдать предупреждение. Это очень полезно для отладки. В eventListener для кнопки мы снова проверяем, чтобы убедиться, что значение не пустое, а затем передаем его в файл PHP.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<?php
$mysqli = new mysqli(«localhost»,»your_user_name»,»your_pass_word»,»your_table_name»);
if (mysqli_connect_errno()) {
    printf(«Can’t connect to SQL Server. Error Code %s\n», mysqli_connect_error($mysqli));
    exit;
}
 
$shade = $_POST[‘shade’];
 
$insert = «INSERT INTO colors (shade) VALUES (‘» . $shade . «‘)»;
$mysqli->query($insert);
printf(«Thanks for the new color!»);
 
$mysqli->close();
?>

Мы устанавливаем соединение и объявляем переменную и присваиваем ей значение, отправленное из нашего приложения с помощью $_POST['YourVarHere']; , Мы создаем оператор вставки, предупреждаем, если он прошел успешно, и закрываем соединение с базой данных.

Предупреждение об удаленной вставке базы данных

Теперь у нас есть новая блестящая запись в нашей базе данных, но, помните, вам, возможно, придется перезапустить симулятор для его отображения!

Удаленная база данных, прочитанная после

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