Обработка обновлений - GyverLibs/GyverPortal GitHub Wiki
В библиотеке есть несколько механизмов, позволяющих автоматически обновлять значения компонентов на странице
AJAX обновления
Данный механизм позволяет обновлять значения конкретных указанных компонентов. Процесс делится на две части:
- В функции конструктора: указание списка имён компонентов, которые должны обновляться
- В функции обработки действий: принятие запросов на обновление и ответ на них актуальными данными
Конструктор
- Список имён в текстовом формате передаётся в
GP.UPDATE()
, разделитель - запятая - К компоненту необязательно должна быть привязана переменная, он получит значение из обновления
int sld;
void build() {
GP.BUILD_BEGIN();
GP.THEME(GP_DARK);
GP.UPDATE("lbl,sld");
//GP.UPDATE("lbl,sld", 500); // + период в мс, умолч. 1000
GP.LABEL("", "lbl"); // без переменной
GP.SLIDER("sld", sld); // из переменной sld
GP.BUILD_END();
}
Обработка
Общий сигнал
- Обработка обновлений происходит в подключенной функции-обработчике действия
- При запросе обновления любого активного компонента на странице (см. таблицу в документации) функция
update()
вернётtrue
- Дальнейшую обработку действий рекомендуется поместить в условие, чтобы микроконтроллер не занимался лишней работой:
void action() {
if (portal.update()) {
// опрос обновлений
Serial.println(portal.updateName());
}
}
При помощи
updateName()
можно узнать имя компонента, запросившего обновление
Ответ вручную
- Для определения запроса обновления компонента нужно передать в
update()
его имя - В этом условии нужно "ответить" на обновление актуальным значением через функцию
answer()
void answer(const String& s; // отправить ответ на обновление
void answer(GPcolor col); // ответ с цветом
void answer(GPdate date); // ответ с датой
void answer(GPtime time); // ответ со временем
void answer(int v); // ответ с числом
void answer(float v, uint8_t dec); // ответ с float и кол-вом знаков
void answer(int16_t* v, int am); // массив int размерностью am, для графика
void answer(int16_t* v, int am, int dec); // + делитель
Пример с лейблом и слайдером выше:
void action() {
if (portal.update()) {
if (portal.update("lbl")) portal.answer(random(100)); // просто ответ
if (portal.update("sld")) portal.answer(sld); // ответ из переменной
}
}
Автоматический ответ
Если у компонента есть глобальная переменная, содержащая актуальное значение, то можно обрабатывать обновления при помощи набора функций:
bool updateString(имя, String& f);
bool updateInt(имя, int f);
bool updateFloat(имя, float f, int dec = 2);
bool updateBool(имя, bool f);
bool updateDate(имя, GPdate f);
bool updateTime(имя, GPtime f);
bool updateColor(имя, GPcolor f);
Функция вернёт true
в момент обновления.
void action() {
if (portal.update()) {
portal.updateInt("sld", sld);
}
}
См. пример actionUpdate
JQUERY обновления
jQuery обновления работают по другому:
- Подключается библиотека jQuery
- Скачивается из интернета (esp должен быть подключен к интернету)
- Отправляется из памяти микроконтроллера (см. скачивание файлов)
- Компоненты помещаются в "блок" обновления
- Значения компонентов должны браться из переменных, которые могут меняться в другом месте программы
- Страница сама "незаметно" частично перезагружается, что приводит к вызову функции-конструктора, после чего компоненты в блоке получают актуальные значения из переменных в функции конструктора
int sld;
String lbl;
void build() {
GP.BUILD_BEGIN();
GP.THEME(GP_DARK);
GP.JQ_SUPPORT(); // поддержка jquery. Файл скачается с https://code.jquery.com/
//GP.JQ_SUPPORT_FILE(); // поддержка jquery, файл скачается из памяти (/gp_data/jquery.js)
GP.JQ_UPDATE_BEGIN(); // начать обновляемый блок с периодом 1 секунда (один на страницу!)
GP.LABEL(lbl, "lbl"); // из переменной
GP.SLIDER("sld", sld); // из переменной
GP.JQ_UPDATE_END(); // закончить обновляемый блок
GP.BUILD_END();
}
Блок JQ_UPDATE также "скрыто" обновляет страницу по клику в любом месте страницы внутри блока, помимо обновления по таймеру
См. пример jQupdate
Перезагрузка страницы
- На страницу добавляется компонент
GP.RELOAD(имя)
- Его имя указывается в списке обновления
GP.UPDATE()
- На указанное имя приходит сигнал
update()
с указанным периодом - Если ответить на него
1
- страница будет перезагружена. Это можно сделать по условию или своему таймеру
void build() {
GP.BUILD_BEGIN();
GP.THEME(GP_DARK);
GP.UPDATE("rel");
GP.RELOAD("rel");
GP.BUILD_END();
}
void action() {
if (portal.update("rel")) portal.answer(1);
}
"Массив" компонентов
Библиотека позволяет создавать и обрабатывать компоненты как "массив", то есть назначить одно и то же имя нескольким компонентам и обращаться к ним по индексу. Синтаксис имени такой: name/sub1/sub2...
, то есть вложенных имён может быть сколько угодно, разделитель - /
. Создадим "массив" лейблов с именами lbl/номер
:
for (int i = 0; i < 5; i++) {
GP.LABEL_BLOCK("", String("lbl/") + i);
GP.BREAK();
}
И добавим их в список обновления:
String s;
// формируем список для UPDATE вида "lbl/0,lbl/1..."
for (int i = 0; i < 5; i++) {
s += "lbl/";
s += i;
s += ',';
}
GP.UPDATE(s);
Теперь для поиска сигнала с такого массива нужно использовать updateSub(имя)
, а внутри условия с ним - updateNameSub(индекс)
для получения саб-имени. Из примера выше updateNameSub(0)
вернёт lbl
, а updateNameSub(1)
- строку с номером лейбла после /
. Ответим строкой вида `"lbl #0: 123"
if (portal.updateSub("lbl")) { // начинается с lbl
// формируем ответ вида "lbl #0: 123"
String s;
s += "lbl #";
s += portal.updateNameSub(1);
s += ":";
s += random(10);
portal.answer(s);
}
См. пример dynamicComponents