Как можно добавить индикатор загрузки для определённых разделов?

У меня есть статический JSON на клиенте, расположенный в файле data.json: 
<pre><code>[
   {
      "id": "settings",
      "name": "Настройки",
      "items": [
         {"id": "game", "name": "Включить игру"},
         {"id": "retest", "name": "Перезагрузить"}
      ]
   },
   {
      "id": "list",
      "name": "Список",
      "items": "server"
   }
]</code></pre> 

Кроме того, у меня есть REST API для получения списка по адресу site.ru/api/list. 

В связи с этим, у меня возникает вопрос: как можно отобразить статические данные из этого JSON, когда для элементов "items", получаемых с сервера, необходимо показать индикатор загрузки? 

Пример того, как это должно выглядеть:
<pre><code class="html">&lt;ul&gt;
   &lt;span&gt;Настройки&lt;/span&gt;
   &lt;li&gt;Включить игру&lt;/li&gt;
   &lt;li&gt;Перезагрузить&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
   &lt;span&gt;Список&lt;/span&gt;
   // Здесь должен отображаться индикатор загрузки… после чего показываются все элементы &lt;li&gt; 
&lt;/ul&gt;</code></pre>
  • 3 января 2025 г. 18:13
Ответы на вопрос 2
Для реализации индикатора загрузки для разделов, где данные загружаются с сервера, можно использовать JavaScript и немного HTML. Когда вы будете загружать данные для определенного раздела, сначала отобразите индикатор загрузки, а после получения данных — уже сами элементы списка. Давайте рассмотрим, как это можно сделать.

### Пример HTML

```html
<div id="content"></div>

<script src="script.js"></script>
```

### Пример JavaScript (`script.js`)

```javascript
// Функция для загрузки данных из JSON и отображения их на странице
async function loadData() {
    // Получаем статические данные из файла data.json (для примера)
    const response = await fetch('data.json');
    const data = await response.json();

    const contentDiv = document.getElementById('content');

    data.forEach(section => {
        const ul = document.createElement('ul');
        
        const titleSpan = document.createElement('span');
        titleSpan.textContent = section.name;
        ul.appendChild(titleSpan);
        
        // Проверяем, нужно ли загружать данные с сервера
        if (section.items === 'server') {
            // Индикатор загрузки
            const loader = document.createElement('li');
            loader.textContent = 'Загрузка...';
            ul.appendChild(loader);

            // Загружаем данные с сервера
            fetch('https://site.ru/api/list')
                .then(response => response.json())
                .then(items => {
                    // Удаляем индикатор загрузки
                    ul.removeChild(loader);
                    
                    // Добавляем загруженные элементы в список
                    items.forEach(item => {
                        const li = document.createElement('li');
                        li.textContent = item.name;
                        ul.appendChild(li);
                    });
                })
                .catch(error => {
                    console.error('Ошибка загрузки данных:', error);
                    ul.removeChild(loader);
                    const errorMessage = document.createElement('li');
                    errorMessage.textContent = 'Ошибка загрузки данных';
                    ul.appendChild(errorMessage);
                });
        } else {
            // Если это статические данные, просто добавляем их
            section.items.forEach(item => {
                const li = document.createElement('li');
                li.textContent = item.name;
                ul.appendChild(li);
            });
        }

        contentDiv.appendChild(ul);
    });
}

// Запускаем загрузку данных
loadData();
```

### Описание

1. **Загрузка статических данных**: Скрипт сначала загружает статический JSON файл (`data.json`). 

2. **Создание списков**: Для каждой секции создается новый элемент `ul`, в который добавляются элементы списка и заглавие секции.

3. **Проверка и загрузка с сервера**: Если секция имеет `"items": "server"`, то показывается индикатор загрузки (в виде элемента списка с текстом "Загрузка..."), после чего происходит асинхронный запрос к API.

4. **Обновление списка**: После получения данных с сервера индикатор загрузки удаляется, и добавляются новые элементы, полученные от сервера.

5. **Обработка ошибок**: Если возникает ошибка при загрузке данных, выводится сообщение об ошибке.

Таким образом, данный код реализует функционал отображения загрузки данных из различных источников (статических и динамических), что делает интерфейс более отзывчивым и приятным для пользователя.
Можно убрать из data.json второй элемент массива(который отвечает за данные с сервера) и поместить его в код компонента в хук useState. При этом стоит установить значения для поля items, как undefined(т.к. данные пока не подгружены). 
const list = useState({
id: 'list',
name: 'Список',
items: undefined,
});

В возвращаемой разметке можем сделать условие, в котором будем проверять значение поля list.items и если его значение будет оличаться от undefined, то отображаем, иначе показываем лоадер.
Пример кода:
const ListComponent = () => {
  const list = useState({
  id: 'list',
  name: 'Список',
  items: undefined,
  });

  useEffect(() => {
  // Код для подгрузки необходимых данных...
  }, []);

  return ( 
    <ul>
       <span>Настройки</span>
       <li>Включить игру</li>
       <li>Перезагрузить</li>
    </ul>
    <ul>
     <span>Список</span>
       {list.items ? (// Необходимая разметка) : <p>Загрузка...</p>}
     </ul>
  )
}
Похожие вопросы