在 FutureProvider 中初始化 StateProvider

Initialize StateProvider in FutureProvider

我的应用程序从检索贯穿整个应用程序流程的重要数据开始 mainContent。大部分数据是静态的

导航屏幕

 Widget stackPages(WidgetRef ref) {
   AsyncValue<Map<String, Object>> mainContent = ref.watch(mainContentFutureProvider);
   return mainContent.when(
     loading: () => Center(child: CircularProgressIndicator()),
     error: (e, st) => Center(child: Text("Error: " + e.toString() + " " + st.toString())), 
     data: (content) {
        return Stack(
          children: [
            _buildOffstageNavigator(ref, "Home", content),
            _buildOffstageNavigator(ref, "Page1", content),
            _buildOffstageNavigator(ref, "Page2", content),
            _buildOffstageNavigator(ref, "Page3", content)
          ],
        );
      },
    );
  }

内容检索(mainContentFutureProvider)

final mainContentFutureProvider= FutureProvider<Map<String, Object>>((ref) async {
    List response = await Future.wait([
       DataController.userInfoDB.getUsers(),
       DataController.userInfoDB.getAnotherList(),
       DataController.userInfoDB.getAnotherList,
    ]);

    return {
      "users": response[0],
      "some_list": response[1],
      "some_list": response[2],
    };
  },
);

用户class(简体)

class User{
  String id;
  String email;
  List<Vehicle> vehicles = [];

  User(this.email, this.vehicles);

  User.fromJson(Map<String, dynamic> json)
      : id = json['id'],
        displayName = json['display_name'],
}

问题

在应用程序的车库屏幕中,用户可以添加或删除车辆。当用户添加或删除车辆时,这会影响应用程序的整个流程。所以这个 User 需要有它的 Notifier class

CurrentUserNotifier

class CurrentUserNotifier extends StateNotifier<User> {
  final User user;

  CurrentUserNotifier(this.user) : super(null);

  void addUserVehicle(Vehicle vehicle) {
    state..vehicles.add(vehicle);
  }

  void removeUserVehicle(int vehicleId) {
    state..vehicles.removeWhere((v) => v.id == vehicleId);
  }
}

currentUserProvider

final currentUserProvider = StateNotifierProvider.family<CurrentUserNotifier, User, User>((ref, user) {
  return CurrentUserNotifier(user);
});

目前我正在检索 List<User> 并且只想让当前用户来自我应用程序中的 provider。如您所见,我从 StateNotifierProvider 中创建了一个 .family,因此我可以执行以下操作:

内容检索(mainContentFutureProvider)

final mainContentFutureProvider= FutureProvider<Map<String, Object>>((ref) async {
    List response = await Future.wait([
       DataController.userInfoDB.getUsers(),
       DataController.userInfoDB.getAnotherList(),
       DataController.userInfoDB.getAnotherList,
    ]);

    --->  currentUserProvider(response[0].first);

    return {
      "users": response[0],
      "some_list": response[1],
      "some_list": response[2],
    };
  },
);

但是对于任何处理我的 User 对象的页面,它需要通过 user 对象作为我的 currentUserProvider

的参数

喜欢:

press: () async {            
  ref.read(currentUserProvider(user).notifier).addUserVehicle(vehicle);
}

我希望提供商只设置一次 StateNotifierProvider 的值,我在这里犯了 pattern/flow 错误吗?

试试这个:

让你的CurrentUserNotifier如此。

final currentUserProvider = StateNotifierProvider<CurrentUserNotifier, User>((ref) {
  return CurrentUserNotifier();
});


class CurrentUserNotifier extends StateNotifier<User?> {

  CurrentUserNotifier() : super(null);

  void setUser(User user){
     state = user;
  }

  void addUserVehicle(Vehicle vehicle) {
    state =  state..vehicles.add(vehicle);
  }

  void removeUserVehicle(int vehicleId) {
    state = state..vehicles.removeWhere((v) => v.id == vehicleId);
  }
}

然后像这样设置user

final mainContentFutureProvider= FutureProvider<Map<String, Object>>((ref) async {
    List response = await Future.wait([
       DataController.userInfoDB.getUsers(),
       DataController.userInfoDB.getAnotherList(),
       DataController.userInfoDB.getAnotherList,
    ]);
     
    ref.read(currentUserProvider.notifier).setUser(response[0].first);

    return {
      "users": response[0],
      "some_list": response[1],
      "some_list": response[2],
    };
  },
);

那么你可以这样做:

press: () async {            
  ref.read(currentUserProvider.notifier).addUserVehicle(vehicle);
}