Итак, мы научились делать экраны и навигацию между ними. Теперь давайте попробуем создать код, который не представлен в виде блоков на экране, но может быть вызван с него.
Для примера возьмем самое простое: зададим пользователю вопрос с тремя вариантами ответов. По действию пользователя, корректный ответ покажет ему сообщение о том что он прав, а остальные, что он ошибся.
Итак, создадим файл question.tsx
, введем начальный код и запустим его.
// Import showToast action
import {showToast} from '@app/ui'
// Screen with 3 buttons and question
const questionScreen = app.screen('/', async function(ctx, req) {
return <screen title="Question">
<text class="section">The Capital of Great Britain</text>
<button onClick={showToast('Click')} class={["secondary","section"]} title="New York"/>
<button onClick={showToast('Click')} class={["secondary","section"]} title="Liverpool"/>
<button onClick={showToast('Click')} class={["secondary","section"]} title="London"/>
</screen>
})
У нас на экране 3 кнопки. В каждой из них 2 класса - secondary и section. Secondary, чтобы сделать кнопку серым цветом. Section, чтобы добавить стандартные отступы. В качестве альтернативы можно использовать блок-оболочку section
для добавления такого отступа к группе элементов.
Все три кнопки делают одинаковое действие - показывают некоторое сообщение на экран. Давайте создадим другое действие и напишем его код под кодом экрана. Для этого, воспользуемся методом app.apiCall
.
// Handler for button
const buttonHandler = app.apiCall('/check', async function(ctx, req) {
return showToast('Clicked');
})
Этот код в файле question.tsx
привязывает обработчик действия к шаблону пути /check
. Обработчик будет отвечать на запрос POST по адресу question~check
.
Чтобы это действие вызывалось при нажатии на кнопку, соответствующий вызов должен быть инициирован в onClick
.Сделаем это для первой кнопки "New York".
<button
onClick={buttonHandler.apiCall({ value: 'New York' })}
class={["secondary","section"]}
>
New York
</button>
Заменим статичный код на значение параметра из запроса:
// Handler for button
const buttonHandler = app.apiCall('/check', async function(ctx, req) {
return showToast('You are clicked: ' + req.body.value);
})
Теперь чуть модифицируем код и сделаем так, чтобы при правильном ответе выдавалось сообщение Correct, а при неправильном другое.
// Handler for button
const buttonHandler = app.apiCall('/check', async function(ctx, req) {
if ( req.body.value === 'London' ) {
return showToast("Correct")
}
else {
return showToast(req.body.value + ' is not correct');
}
})
Проставим действия во все три кнопки и проверим, как это работает.
const questionScreen = app.screen('/', async function(ctx, req) {
return <screen title="Question">
<text class="section">The Capital of Great Britain</text>
<button onClick={buttonHandler.apiCall({ value: 'New York'})} class={["secondary","section"]} title="New York"/>
<button onClick={buttonHandler.apiCall({ value: 'Liverpool'})} class={["secondary","section"]} title="Liverpool"/>
<button onClick={buttonHandler.apiCall({ value: 'London'})} class={["secondary","section"]} title="London"/>
</screen>
})
Мы видим что получилось много повторяющегося кода. Чтобы этого избежать мы отделим данные от представления и модифицируем код так, чтобы в нем не было повторов. Заодно чуть перепишем код проверки чтобы он стал короче.