Flutter 表单与 Riverpod 绑定

问题描述 投票:0回答:1

我是 flutter 和 Riverpod 的新手,我正在尝试使用提供程序实现一些基本表单数据绑定。

我有一个代表正在填写的表单的模型,并且我有一个通知程序提供程序设置来向消费者提供该模型。但是,当值更改时,我无法重建复选框小部件,因此它实际上从未显示为选中状态。即使表单数据中的基础值是正确的。

这是我正在使用的代码:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class MyFormData {
  String name;
  bool isSelected;

  MyFormData(
    this.name,
    this.isSelected
  );
}

class MyFormController extends Notifier<MyFormData>{

  @override
  MyFormData build() {
    return MyFormData("test", false);
  }

  bool get isSelected => state.isSelected;
  set isSelected(value) {
    state.isSelected = value;
    state = state;
  }
}

final myFormControllerProvider = NotifierProvider<MyFormController, MyFormData>(MyFormController.new);

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Home(),
    );
  }
}

class Home extends ConsumerWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final formData = ref.watch(myFormControllerProvider);

    return Scaffold(
      appBar: AppBar(title: const Text("My Form")),
      body: Center(
        child: Card(
          child:Row(
            children: [
              Checkbox(
                value: formData.isSelected, 
                onChanged: (value) => ref.read(myFormControllerProvider.notifier).isSelected = value!),
              const Text('I am a Checkbox')
            ],
          )
        )
      )
    );
  }
}

我觉得这遵循我找到的每个复选框绑定的“示例教程”,但我知道我错过了一些东西。谁能帮助确定我做错了什么?

flutter dart riverpod
1个回答
0
投票
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:equatable/equatable.dart';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
part  'this_file_name.freezed.dart';
part  'this_file_name.g.dart';

@freezed
class MyFormData extends Equatable with _$MyFormData {    
  const MyFormData._();
  const factory MyFormData({
    required String name,
    required  bool isSelected,
  }) = _MyFormData;
 
  @override
  List<Object?> get props => [name, isSelected];
}


@riverpod
class MyFormController  extends _$MyFormController {
 
  @override
  MyFormData build() =>  MyFormData("test", false);
              
      
    bool get isSelected => state.isSelected;
    set isSelected(value) {
      state = state.copyWith(isSelected: value);
    }
  }
  
  
  void main() {
    runApp(const ProviderScope(child: MyApp()));
  }
  
  class MyApp extends StatelessWidget {
    const MyApp({Key? key}) : super(key: key);
  
    @override
    Widget build(BuildContext context) => const MaterialApp(
        home: Home(),
      );
  }
  
  class Home extends ConsumerWidget {
    const Home({super.key});

    @override
    Widget build(BuildContext context, WidgetRef ref) {
final formData = ref.watch(myFormControllerProvider.select(data => data.isSelected)); 
// prevent unwanted updates: if this widget should updated only if the user change the isSelected field, then this will help (i.e. if you change the name this widget will not repainted).

return Scaffold(
  appBar: AppBar(title: const Text("My Form")),
  body: Center(
    child: Card(
      child:Row(
        children: [
          Checkbox(
            value: formData.isSelected, 
            onChanged: (value) => ref.read(myFormControllerProvider.notifier).isSelected = value!),
          const Text('I am a Checkbox')
        ],
      )
    )
  )
);

} }

应该可以! 试试这个(我没有尝试过......但应该可行)。 不要忘记添加到您的 pubspec.yaml :

    dependencies:  
      equatable: ^2.0.5
      riverpod_annotation: ^2.3.5
    
    dev_dependencies:
      build_runner: ^2.4.8
      riverpod_generator: ^2.4.0
© www.soinside.com 2019 - 2024. All rights reserved.