如何将使用提供程序的项目转换为使用 flutter_riverpod 提供程序?

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

以前我一直在使用提供程序,因为它很简单,但现在我想检查我们的

flutter_riverpod
我无法理解我拥有的一些代码,我想知道你是否可以帮助我将其转换为 flutter_river pod,这样我有一个主意

首先这是使用

provider

的项目

我有这样的主屏幕,可以从 firebase 获取数据

class _MainScreenState extends State<MainScreen> {
  int _currentIndex = 0;
  bool _isLoading = true;
  final double smallScreenSize = 600;
  final double largeScreenSize = 800;
  final double smallIconSize = 18;
  final double largeIconSize = 24;
  Stream<List<Map<String, dynamic>>>? captainDataStream;
  Stream<List<Map<String, dynamic>>>? firstOfficerDataStream;
  Stream<List<Map<String, dynamic>>>? cabinCrewStream;
  @override
  void initState() {
    //print('mainScreen initstate called');
    super.initState();
    _loadData();
  }
  Future<void> _loadData() async {
    //await FirebaseServices.uploadInitialData();
    await Provider.of<RosterDataProvider>(context, listen: false)
        .getCaptainDatabase();
        //use riverpod provider to get data
    await Provider.of<RosterDataProvider>(context, listen: false)
        .getFirstOfficerDatabase();
    await Provider.of<RosterDataProvider>(context, listen: false)
        .getCabinCrewDatabase();
    setState(() {
      _isLoading = false;
    });
  }
  @override
  Widget build(BuildContext context) {

现在在我的

changeNotifier
我有这样的

class RosterDataProvider extends ChangeNotifier {
  final List<Map<String, dynamic>> _captainSnapShot = [];
  final List<Map<String, dynamic>> _firstOfficerSnapShot = [];
  final List<Map<String, dynamic>> _cabinCrewSnapShot = [];
  final List<PlutoRow> _captainRows = [];
  final List<PlutoRow> _firstOfficerRows = [];
  final List<PlutoRow> _cabinCrewRows = [];
  final List<PlutoColumn> _captainColumn = [];
  PlutoGridMode _mode = PlutoGridMode.selectWithOneTap;
  PlutoGridMode get mode => _mode;
  List<Map<String, dynamic>> get captainSnapShot => _captainSnapShot;
  List<Map<String, dynamic>> get firstOfficerSnapShot => _firstOfficerSnapShot;
  List<Map<String, dynamic>> get cabinCrewSnapShot => _cabinCrewSnapShot;
  List<PlutoRow> get captainRows => _captainRows;
  List<PlutoRow> get firstOfficerRows => _firstOfficerRows;
  List<PlutoRow> get cabinCrewRows => _cabinCrewRows;
  List<PlutoColumn> get captainColumn => _captainColumn;
  set mode(PlutoGridMode mode) {
    _mode = mode;
    notifyListeners();
  }
  void setCaptainRows(List<PlutoRow> row) {
    print('setCaptainRows######');
    _captainRows.clear();
    _captainRows.addAll(row);
    notifyListeners();
  }
  void setFirstOfficerRows(List<PlutoRow> row) {
    _firstOfficerRows.clear();
    _firstOfficerRows.addAll(row);
    notifyListeners();
  }
  void setCabinCrewRows(List<PlutoRow> row) {
    _cabinCrewRows.clear();
    _cabinCrewRows.addAll(row);
    notifyListeners();
  }
  Future<void> getCaptainDatabase() async {
    final DatabaseReference databaseReference = FirebaseDatabase.instance.ref();
    final captainNode = databaseReference.child('CAPTAIN_DATA');
    try {
      final event = await captainNode.once();
      final captainData = event.snapshot.value as Map<dynamic, dynamic>;
      captainData.entries.map((entry) {
        final Map<String, dynamic> captain = {
          'SN': entry.value['SN'] ?? 'ERR' as Map<String, dynamic>,
          'NAME': entry.value['NAME'] ?? 'ERR' as Map<String, dynamic>,
          'CODE': entry.value['CODE'] ?? 'ERR' as Map<String, dynamic>,
        };
        _captainSnapShot.add(captain);
        return captain;
      }).toList();
    } catch (error) {
      // print("Error loading data: $error");
    }
    notifyListeners();
  }
  Future<void> getFirstOfficerDatabase() async {
    // print('reached captainDatabase Download');
    final DatabaseReference databaseReference = FirebaseDatabase.instance.ref();
    final firstOfficerNode = databaseReference.child('FIRST_OFFICER_DATA');
    try {
      final event = await firstOfficerNode.once();
      final firstOfficerData = event.snapshot.value as Map<dynamic, dynamic>;
      firstOfficerData.entries.map((entry) {
        final Map<String, dynamic> firstOfficer = {
          'SN': entry.value['SN'] ?? 'ERR' as Map<String, dynamic>,
          'NAME': entry.value['NAME'] ?? 'ERR' as Map<String, dynamic>,
        };
        parseCommonNestedData(entry, firstOfficer);
        _firstOfficerSnapShot.add(firstOfficer);
        return firstOfficer;
      }).toList();
    } catch (error) {
      // print("Error loading data: $error");
    }
    notifyListeners();
  }
}

接下来我将在其他类中使用来自 RosterDataProvider 的数据,如下所示

class Leave extends StatefulWidget {
  const Leave({super.key});
  @override
  State<Leave> createState() => _LeaveState();
}
class _LeaveState extends State<Leave> {
  List<Map<String, dynamic>>? captainData;
  List<Map<String, dynamic>>? firstOfficerData;
  List<Map<String, dynamic>>? cabinCrewData;
  PlutoGridStateManager? _stateManager;
  List<Map<String, dynamic>>? dataCabin;
  List<PlutoColumn>? columns;
  List<PlutoRow>? plutoRows;
  @override
  void initState() {
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    captainData =
        Provider.of<RosterDataProvider>(context, listen: false).captainSnapShot;
    firstOfficerData = Provider.of<RosterDataProvider>(context, listen: false)
        .firstOfficerSnapShot;
    cabinCrewData = Provider.of<RosterDataProvider>(context, listen: false)
        .cabinCrewSnapShot;
    return Scaffold(
      backgroundColor: Theme.of(context).primaryColor,
      body: DefaultTabController(
        length: 3,
        child: Column(
          children: [
            const TabBar(
              tabs: [
                Tab(text: 'Captain Leave'),
                Tab(text: 'First Officer Leave'),
                Tab(text: 'Cabin Crew Leave'),
              ],
              indicatorColor: Color.fromARGB(255, 102, 249, 4),
              indicatorSize: TabBarIndicatorSize.label,
            ),
            Expanded(
              child: TabBarView(
                children: [
                  buildGrid(captainData!, "captain"),
                  buildGrid(firstOfficerData!, "firstOfficer"),
                  buildGrid(cabinCrewData!, "cabinCrew"),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

所以这就是正在发生的事情,主屏幕-->changenotifier-->离开,我无法在RiverPod中理解这个概念,我怎样才能实现这个确切的行为?

flutter dart provider riverpod
1个回答
0
投票

您需要将

RosterDataProvider
拆分为许多不同的 Riverpod 提供者,并定义不同的方法来更改每个提供者的逻辑。对于简单数据类型,请使用
StateProvider
,对于集合,请使用
NotifierProvider
。例如,让我展示一个简单的案例
PlutoGridMode
:

final plutoGridModeProvider = StateProvider((_) => PlutoGridMode.selectWithOneTap);

现在在你的小部件中:

class PlutoGridModeWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context) {
    final mode = ref.watch(plutoGridModeProvider);
    return (
      children: [
        ElevatedButton(
          child: Text('New mode'),
          onPressed: () => 
              ref.read(plutoGridModeProvider.notifier).update((oldState) => PlutoGridMode.selectAll)},
        ),
        const SizedBox(width: 10),
      ],
    );
  }
}

只要您单击按钮(在此示例中一次:),您的小部件就会自行重建。


如果需要异步[数据|加载|错误]状态,也可以考虑使用

AsyncNotifier
,或者将
Notifier
与必要的密封类一起使用。这里有一个很好的例子:

© www.soinside.com 2019 - 2024. All rights reserved.