Фреймворк Marko предлагает мощный механизм для работы с динамическими веб-приложениями, где данные на клиенте часто обновляются без необходимости перезагрузки страницы. Это становится возможным благодаря использованию асинхронных вызовов и интеграции с современными средствами загрузки данных. Основной подход заключается в том, чтобы разделить логику загрузки данных и рендеринг, позволяя динамически обновлять интерфейс на основе полученных данных.
Marko поддерживает асинхронную загрузку данных, что позволяет серверу
и клиенту работать более эффективно. Этот механизм позволяет сначала
рендерить страницу на сервере, а затем обновлять её части на клиенте без
перезагрузки, обращаясь к серверу за новыми данными. Один из ключевых
аспектов — это использование встроенной поддержки асинхронных функций,
таких как async/await, для получения данных с сервера или
через API.
data и асинхронных запросовПри рендеринге страницы на сервере, Marko может использовать специальные данные, переданные в шаблон. Чтобы асинхронно загрузить данные, можно использовать следующую схему:
// Серверный код
const getData = async () => {
return await fetch('https://api.example.com/data')
.then(response => response.json());
};
module.exports = async () => {
const data = await getData();
return {
data: data
};
};
Этот код выполняет запрос к внешнему API и передает результат в шаблон. В Marko можно работать с полученными данными на клиенте с помощью встроенных методов рендеринга.
Для организации загрузки данных на клиенте можно создать компонент Marko, который будет отвечать за асинхронное получение данных. Использование компонентов Marko позволяет разделить логику загрузки данных и рендеринг, что упрощает структуру приложения.
Пример компонента, который запрашивает данные и отображает их:
// my-component.marko
import { createComponent } from "marko";
export default createComponent({
async onCreate() {
this.data = await fetchDataFromAPI();
},
template: `
<div>
<h2>Загруженные данные:</h2>
<ul>
<li for="item in data">{{ item.name }}</li>
</ul>
</div>
`
});
В этом примере асинхронная функция fetchDataFromAPI
загружает данные и передает их в компонент. Затем, с использованием
синтаксиса Marko, данные отображаются в виде списка.
Одним из важных аспектов работы с асинхронными запросами является правильная обработка ошибок. Даже в случае с успешным запросом данные могут быть пустыми или иметь неожидаемую структуру. Для этого можно добавить блоки для обработки ошибок и состояния загрузки.
Пример улучшенной версии компонента с обработкой ошибок и состояния загрузки:
// my-component.marko
import { createComponent } from "marko";
export default createComponent({
async onCreate() {
try {
this.isLoading = true;
this.data = await fetchDataFromAPI();
this.isLoading = false;
} catch (error) {
this.isLoading = false;
this.error = 'Ошибка при загрузке данных.';
}
},
template: `
<div>
<if(condition="isLoading")>
<p>Загрузка...</p>
</if>
<if(condition="error")>
<p class="error">{{ error }}</p>
</if>
<ul>
<li for="item in data">{{ item.name }}</li>
</ul>
</div>
`
});
Здесь добавлены состояния для загрузки и ошибки, что улучшает пользовательский опыт, показывая пользователю соответствующую информацию в случае проблем с запросом данных.
Для реализации более сложных сценариев, когда данные на странице должны обновляться в ответ на действия пользователя, можно использовать клиентскую логику. Например, для загрузки новых данных при изменении фильтров или параметров поиска можно использовать фреймворк с интеграцией с JavaScript.
Пример динамической загрузки данных при изменении фильтра:
// my-filter-component.marko
import { createComponent } from "marko";
export default createComponent({
async onMount() {
this.filter = 'all';
this.updateData();
},
async updateData() {
const data = await fetchDataWithFilter(this.filter);
this.data = data;
},
template: `
<div>
<SELECT oncha nge="setFilter(event)">
<option value="all">Все</option>
<option value="active">Активные</option>
<option value="completed">Завершенные</option>
</select>
<ul>
<li for="item in data">{{ item.name }}</li>
</ul>
</div>
`
});
В данном примере, при изменении фильтра, будет вызываться функция
updateData, которая отправляет запрос на сервер с
соответствующим фильтром и обновляет данные на странице. Этот подход
позволяет сделать интерфейс более интерактивным, не перегружая
страницу.
Для работы с большими объемами данных, таких как списки или таблицы, важно использовать пагинацию или ленивую загрузку данных. В Marko можно реализовать эти подходы с помощью асинхронных запросов и динамического рендеринга контента.
Пример ленивой загрузки данных:
// lazy-load-component.marko
import { createComponent } FROM "marko";
export default createComponent({
async onMount() {
this.page = 1;
this.itemsPerPage = 10;
await this.loadData();
},
async loadData() {
const data = await fetchDataForPage(this.page, this.itemsPerPage);
this.data = data;
},
async loadMore() {
this.page++;
await this.loadData();
},
template: `
<div>
<ul>
<li for="item in data">{{ item.name }}</li>
</ul>
<button oncl ick="loadMore()">Загрузить еще</button>
</div>
`
});
В этом примере данные загружаются постранично с помощью кнопки «Загрузить еще», что позволяет эффективно работать с большими наборами данных. Пагинация или ленивые загрузки данных значительно повышают производительность и сокращают время отклика на странице.
Загрузка данных на клиенте с использованием Marko предоставляет гибкие и мощные инструменты для работы с динамическим контентом. Асинхронные запросы, обработка ошибок, клиентская логика для обновления данных и механизмы ленивой загрузки позволяют создавать эффективные и отзывчивые веб-приложения. Marko предоставляет богатую экосистему для реализации различных сценариев загрузки данных, что помогает значительно улучшить пользовательский опыт и производительность приложений.