Перейти к основному содержимому

FFAppState

Предварительные требования

В этом руководстве используется пример сгенерированного кода из демо-приложения EcommerceFlow.
Чтобы просмотреть сгенерированный код напрямую, откройте репозиторий на GitHub.

Класс FFAppState в FlutterFlow служит центральным узлом для управления глобальным состоянием приложения.
Он реализован как singleton — то есть существует только один экземпляр этого класса на протяжении всего жизненного цикла приложения.
Этот класс расширяет ChangeNotifier, что позволяет виджетам подписываться на изменения состояния и реагировать на них.

Он включает методы для инициализации и обновления сохранённого состояния приложения, а также определяет различные переменные состояния с соответствующими геттерами и сеттерами для их изменения.

Ниже приведён базовый шаблон класса, взятый из сгенерированного кода демо-приложения eCommerceFlow:

class FFAppState extends ChangeNotifier {
static FFAppState _instance = FFAppState._internal();

factory FFAppState() {
return _instance;
}

FFAppState._internal();

static void reset() {
_instance = FFAppState._internal();
}

void update(VoidCallback callback) {
callback();
notifyListeners();
}

// Переменная состояния приложения примитивного типа с геттером и сеттером
bool _enableDarkMode = false;

bool get enableDarkMode => _enableDarkMode;

set enableDarkMode(bool value) {
_enableDarkMode = value;
}
}

_enableDarkMode — это переменная состояния приложения, созданная разработчиком, которая имеет собственные геттер и сеттер.


Перестроение при обновлении AppState

При обновлении переменной AppState из Action Flow Editor вы можете выбрать один из типов обновления:
Rebuild All Pages, Rebuild Current Page или No Rebuild в настройках действия.
Рассмотрим, как изменяется сгенерированный код в зависимости от выбранного варианта.

Rebuild Current Page

Если разработчик выбирает тип обновления Rebuild Current Page, вызывается соответствующий setter.
Сразу после этого выполняется setState(() {});, что обновляет только текущую страницу.

Пример сгенерированного кода при обновлении состояния enableDarkMode в триггере onInitialization на странице ProductListPage:

SchedulerBinding.instance.addPostFrameCallback((_) async {
FFAppState().enableDarkMode = !(FFAppState().enableDarkMode ?? true);
setState(() {});
});

Rebuild All Pages

В этом случае тип обновления установлен как Rebuild All Pages, что означает:
сначала вызывается setter, затем — метод update().
Метод update() внутри себя вызывает notifyListeners(), что важно для обновления всех виджетов, зависящих от этой переменной.

SchedulerBinding.instance.addPostFrameCallback((_) async {
FFAppState().enableDarkMode = !(FFAppState().enableDarkMode ?? true);
FFAppState().update(() {});
});
Обновление App State из пользовательского кода

При обновлении переменных состояния из пользовательского кода (например, Custom Actions)
необходимо обязательно вызывать функцию update(), чтобы изменения отразились на всех страницах.
Пример:

FFAppState().update(() => FFAppState().enableDarkMode = !(FFAppState().enableDarkMode ?? true));

No Rebuild

В этом варианте вызывается только setter, без setState или update.
Это означает, что переменная обновляется, но интерфейс после этого не перестраивается.


watch<FFAppState>

Когда вы добавляете действие Update App State
в Action Flow Editor, в метод build соответствующих страниц добавляется строка:

@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
...

Использование context.watch<FFAppState>() делает виджет подписчиком изменений класса FFAppState.
При каждом изменении состояния этот виджет автоматически перестраивается, отображая актуальные данные.
Это гарантирует, что интерфейс всегда синхронизирован с текущим состоянием приложения.


Управление AppState<List>

Когда вы добавляете в FlutterFlow переменную состояния типа List,
генерируются дополнительные функции для её управления — геттер, сеттер,
а также методы для добавления, удаления и обновления элементов.
Это обеспечивает удобное и согласованное управление списком, поддерживая корректность состояния приложения.
Ниже приведён пример на основе списка координат LatLngList.

late LoggableList<LatLng> _LatLngList =
LoggableList([LatLng(37.4071594, -122.0775312), LatLng(40.7358633, -73.9910835)]);

List<LatLng> get LatLngList => _LatLngList?..logger = () => debugLogAppState(this);

set LatLngList(List<LatLng> value) {
if (value != null) {
_LatLngList = LoggableList(value);
}

debugLogAppState(this);
}

void addToLatLngList(LatLng value) {
LatLngList.add(value);
}

void removeFromLatLngList(LatLng value) {
LatLngList.remove(value);
}

void removeAtIndexFromLatLngList(int index) {
LatLngList.removeAt(index);
}

void updateLatLngListAtIndex(
int index,
LatLng Function(LatLng) updateFn,
) {
LatLngList[index] = updateFn(_LatLngList[index]);
}

void insertAtIndexInLatLngList(int index, LatLng value) {
LatLngList.insert(index, value);
}

Эти функции автоматически создаются для удобного управления переменными-списками состояния приложения.
Вот что они делают:

  • Список LatLngList инициализируется как приватная переменная _LatLngList типа LoggableList, обеспечивающая логирование изменений.
  • get LatLngList предоставляет доступ к списку.
  • set LatLngList заменяет весь список новым и вызывает debugLogAppState.
  • addToLatLngList добавляет элемент.
  • removeFromLatLngList удаляет конкретный элемент.
  • removeAtIndexFromLatLngList удаляет элемент по индексу.
  • updateLatLngListAtIndex обновляет элемент по индексу с помощью функции updateFn.
  • insertAtIndexInLatLngList вставляет элемент на указанную позицию, сдвигая остальные.

Как создать переменные App State

Чтобы узнать больше о создании и использовании переменных состояния приложения,
см. руководство App State.