flutter 无法使用StateNotifier和StateNotifierProvider生成和显示子任务

h9vpoimq  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(132)

我试图使用Riverpod包在Flutter中生成和显示子任务。我有一个SubtaskNotifier,它用AsyncValue状态扩展了StateNotifier。SubtaskNotifier有一个generateSubtasks方法,它用一个生成子任务的FutureProvider来更新它的状态。但是它不能正常工作,我能够获取数据,但我看不到加载状态。我想实现的是,我想显示一个按钮,触发生成子任务,并显示加载,如果有数据,隐藏按钮并显示数据

final generateGoalTaskSubtasksControllerProvider =
    FutureProvider.family<List<String>, GoalTask>((ref, task) async {
  final chatAPIController = ref.read(chatAPIControllerProvider.notifier);
  final subtasks =
      await chatAPIController.generateGoalTaskSubtasksController(task);
  ref.read(goalTaskSubtasksListProvider.notifier).updateTasks(subtasks);
  return subtasks;
});

下面是SubtaskNotifier:

class SubtaskNotifier extends StateNotifier<AsyncValue<List<String>>> {
  final GoalTask goalTask;
  final ProviderContainer container;

  SubtaskNotifier(this.container, this.goalTask) : super(AsyncValue.data([]));

  void generateSubtasks() {
    state =
        container.read(generateGoalTaskSubtasksControllerProvider(goalTask));
  }
}

我正在尝试使用www.example.com创建SubtaskNotifier示例StateNotifierProvider.family:

final subtaskNotifierProvider = StateNotifierProvider.family<SubtaskNotifier,
    AsyncValue<List<String>>, GoalTask>((ref, task) {
  return SubtaskNotifier(ref.container, task);
});

我想在一个小部件(SubtaskGenerator)中显示这些子任务,并且我想在按下按钮(“GenerateSubtasks”)时触发子任务的生成。
下面是SubtaskGenerator:

class SubtaskGenerator extends ConsumerWidget {
  final GoalTask goalTask;

  const SubtaskGenerator({Key? key, required this.goalTask}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final theme = ref.read(themeProvider);
    final subtaskNotifier =
        ref.watch(subtaskNotifierProvider(goalTask).notifier);

    return subtaskNotifier.state.when(
      data: (subtasks) {
        return Column(
          children: [
            if (subtasks.isEmpty)
              Center(
                child: TextButton(
                  child: Text('Generate Subtasks'),
                  onPressed: () {
                    subtaskNotifier.generateSubtasks();
                  },
                ),
              ),
            for (String subtask in subtasks)
              ListTile(
                title: Text(subtask),
                trailing: IconButton(
                  icon: Icon(
                    Icons.delete,
                    color: theme.colorScheme.onError,
                  ),
                  onPressed: () {},
                ),
              ),
            if (subtasks.isEmpty)
              Text(
                "No subtasks Available",
                style: GoogleFonts.poppins(color: theme.colorScheme.onTertiary),
              ),
          ],
        );
      },
      error: (error, stacktrace) {
        return const Center(child: Text("Error occurred"));
      },
      loading: () {
        return Center(child: AnimatedEmojiLoadingIndicator());
      },
    );
  }
}
bxjv4tth

bxjv4tth1#

你可能错过了这个:

void generateSubtasks() {
  state = const AsyncValue.loading();
  final tasksFuture = container.read(generateGoalTaskSubtasksControllerProvider(goalTask).future);
  state = await AsyncValue.guard(() => tasksFuture);
}

另外,在build方法中使用ref.watch(provider),否则您的小部件将无法重建:

Widget build(BuildContext context, WidgetRef ref) {
  final theme = ref.watch(themeProvider);
  final subtaskNotifier = ref.watch(subtaskNotifierProvider(goalTask));

  ...

  onPressed: () {
    ref.read(subtaskNotifierProvider(goalTask).notifier)
         .generateSubtasks();
  },

为方便起见,请定义一个公用字段:

var subtaskProvider = subtaskNotifierProvider(goalTask);
  final subtaskNotifier = ref.watch(subtaskProvider);

  ...

  onPressed: () {
    ref.read(subtaskProvider.notifier).generateSubtasks();
  },

相关问题