Обзор:
Эта серия из четырех блогов будет служить пошаговым руководством по настройке панели администратора с помощью WordPress на основе WooCommerce (часть 2). Это легко поможет вам управлять инвентарем ваших продуктов, чтобы пользователи могли покупать продукты без проблем, используя клиенты iOS и Android, созданные с использованием Flutter, который также обсуждался позже (части 1, 3 и 4).
Часть 1: приложение электронной коммерции с использованием Flutter - Часть 1: пользовательский интерфейс
Часть 2: приложение электронной коммерции с использованием Flutter - Часть 2: Интеграция с приборной панелью WooCommerce
Часть 3: приложение электронной коммерции с использованием Flutter - Часть 3: удаленные данные
Часть 4: приложение электронной коммерции с использованием Flutter - Part 4: Scoped Model
Стек технологий:
- Флаттер
- WordPress
- WooCommerce
Создание приложения Flutter E-Commerce с удаленными данными
В этой части мы заменим статические данные данными, полученными из API, и отобразим их в соответствующих виджетах.
ProductsListPage:
Мы запрашиваем наш URL-адрес, который возвращает список продуктов на основе categoryId. Полученный нами ответ выглядит следующим образом:
Это похоже на массив объектов JSON, где каждый объект JSON является Продуктом. Объект JSON продукта содержит все примитивные данные (String, int, bool) и несколько других массивов JSON, таких как categories
и images
. Массив categories
содержит объекты JSON, представляющие категорию, а массив images
содержит объекты JSON, представляющие изображение. Следовательно, мы создаем 3 класса моделей с именами Product
, Category
и AnyImage
.
На ProductsListPage
каждая строка представляет 2 продукта. Следовательно, мы модифицируем наш ProductsListItem
для размещения 2 продуктов следующим образом:
Чтобы начать получение данных из удаленного API, мы используем пакет http
и добавляем его в файл pubspec.yaml
:
Затем, чтобы использовать этот пакет в нашем ProductsListPage
, мы импортируем его следующим образом:
import 'package:http/http.dart' as http;
Теперь мы можем, наконец, получить удаленные данные, как показано в методе ниже:
Это может показаться немного сложным, поэтому давайте рассмотрим его строка за строкой:
Future<dynamic> _getProductsByCategory(categoryId, pageIndex) async
У нас есть метод, который принимает categoryId
и pageIndex
(для разбивки на страницы). Тип возврата - Future
, поскольку этот метод выполняет вызов API, и время ответа для него не фиксировано.
Future - это объект, представляющий отложенное вычисление
Future
доступен в пакете dart:async
, и мы импортируем его для того же. Ключевое слово async
в конце объявления метода используется для того, чтобы этот метод выполнялся в другом потоке, то есть async
hronously.
Мы используем ключевое слово await
перед нашим сетевым вызовом, используя http.get(..)
, чтобы приостановить выполнение остальной части метода до завершения этого Future
. Затем мы просто присваиваем его переменной response
. Также обратите внимание, что у нас есть файл с именем remote_config.dart
, который содержит static final Map<dynamic, String>
, как показано ниже:
Этот класс помогает нам определять наши сетевые константы в одном месте.
Наконец, мы возвращаем dynamic
из этого метода, выполняя return json.decode(response.body)
.
Затем мы добавляем метод, который будет вызывать наш _getProductsByCategory()
метод и также анализировать ответ:
Здесь dataFromResponse
переменная будет иметь тип dynamic
, поскольку это то, что мы вернули с помощью json.decode(response.body)
.
Наш ответ - это массив продуктов, поэтому мы можем перебирать dynamic
(в нашем случае массив) с помощью метода forEach()
. Сначала мы анализируем images
из ответа продукта, затем categories
этого продукта, а затем, наконец, мы анализируем остальные детали продукта. Затем мы добавляем наш проанализированный продукт в productsList
. Мы возвращаем тот же список из этого метода.
Теперь нам просто нужно изменить наш ListView.builder
виджет в _buildProductsListPage()
методе, заменив фиктивные данные удаленными данными. Для этого мы оборачиваем наш виджет ListView.builder
в FutureBuilder
следующим образом:
Давайте сначала сосредоточимся на инструкции switch
, которая применяется к snapshot
ConenctionState
. ConnectionState
- это enum
, который дает нам состояние подключения к асинхронным вычислениям. Константы enum
: active
, none
, waiting
и done
. Их значения довольно очевидны из самих названий, и вы можете узнать больше о них здесь.
Мы отображаем виджет CircularProgressIndicator
или виджет Text
с сообщением об ошибке на основе ConnectionState
. Когда у нас наконец есть наш snapshot
, готовый к использованию после завершения асинхронной операции, то есть ConnectionStatus.done
, мы заполняем наш ListView
.
Все, что ниже нашего AppBar
, можно прокручивать. У нас есть Container
, который отображает значки фильтров для СОРТИРОВКИ и УТОЧНЕНИЯ, а ниже у нас есть список наших продуктов. Таким образом, первый index
из ListView.builder
возвращает контейнер, содержащий значок фильтра. Это достигается с помощью _buildFilterWidgets()
методов.
Наш ListView.builder
имеет itemCount
из 8. Это потому, что сейчас мы запрашиваем только 6 продуктов со страницы 1, как указано в URL.
6 из 8 - для продуктов. +1 для контейнера фильтра, который имеет кнопки СОРТИРОВАТЬ и УТОЧНИТЬ. +1 за SizedBox
, который мы добавили внизу продуктов, чтобы занять дополнительное место. Следовательно, itemCount
получается количество продуктов (6) + 1 + 1, то есть 8.
itemBuilder
устанавливает контейнер фильтра на index
0 и SizedBox
на последний index
, т.е. 7.
Поскольку каждый элемент в нашем ListView
представляет собой Row
из 2 продуктов, мы возвращаем новый элемент списка, т.е. ProductsListItem
с нечетным index
, и просто возвращаем пустой Container
, не занимающий места с четным index
.
Все, что мы сделали до сих пор, поможет нам отобразить в нашем списке только 6 (или любое фиксированное количество) продуктов, все сразу. Чтобы отобразить все продукты с помощью разбивки на страницы, нам нужно будет увеличивать pageIndex
всякий раз, когда пользователь прокручивает до последнего элемента в текущем списке отображаемых элементов, а затем получать еще X продуктов. Мы рассмотрим эту ситуацию в части 4.
ProductDetailPage:
Поскольку у нас уже есть все сведения о каждом продукте на ProductsListPage
, мы можем просто перейти на страницу сведений, нажав элемент продукта в списке, и передать вместе с ним наш объект продукта:
Затем нам нужно обновить наш ProductDetailPage
, чтобы у него был конструктор, который принимает Product
в свои аргументы. Затем мы передаем полученный Product
классу _ProductDetailPageState
:
Затем мы, наконец, заменяем все наши статические данные удаленными данными, используя Product
, полученный в этом классе.
Полный код части 3 можно найти здесь. Полный исходный код этого руководства можно найти здесь.
Вы можете прочитать Часть 1 здесь и Часть 2 здесь.
Подпишитесь на GeekyAnts, чтобы получать уведомления, как только часть 4 выйдет!
Заинтересованы в изучении Flutter? Перейдите на FlutterLearn, наш новейший образовательный портал по Flutter.
Вы можете оформить заказ более обширного решения на FlutterMarket, торговой площадке, разработанной GeekyAnts, имеющей потрясающие продукты Flutter:
Этот блог написали Рохан Танеджа и Пушкар Кумар из команды Flutter в GeekyAnts.