首页 > 解决方案 > Flutter 提供者没有响应 notifyListeners

问题描述

我有一个应用程序,允许用户从列出整个美国河流的 API 中查看河流水位计数据。用户可以将仪表保存为收藏夹,然后显示在收藏夹视图中。收藏夹按 ID 存储在用户默认值中。收藏夹视图是通过使用用户默认构造的收藏夹视图模型填充的。收藏夹显示在列表视图中,当点击一个时,应用程序会加载详细信息视图。在详细信息视图中,用户可以选择删除收藏夹。当使用后退按钮返回收藏夹视图时,收藏夹视图应该反映更改,但事实并非如此。我正在使用 Flutter Provider,这是我的第一个实现。

我在 main 中定义提供程序,因为我需要在整个应用程序中访问它。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  setupServiceLocator();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
      .then((_) {
    runApp(
      ChangeNotifierProvider(
        create: (context) => FavoritesViewModel(),
        child: MyApp(),
      )
    );
  });
} 

我的列表视图

class _FavoritesView extends State<FavoritesView> {
  FavoritesViewModel viewModel = FavoritesViewModel(); // serviceLocator<FavoritesViewModel>();

  @override
  void initState() {
    viewModel.loadFavorites();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Consumer<FavoritesViewModel>(
      builder: (context, model, child) => Scaffold(
        appBar: AppBar(
          title: Text('=Favorites='),
        ),
        body: ListView.builder(
          itemCount: model.favorites.length,
          itemBuilder: (context, index) {
            return FavoriteCard(model.favorites[index], Key(model.favorites[index]));
          },
        ),
      ),
    );
  }

收藏夹视图模型

class FavoritesViewModel extends ChangeNotifier {

  List<String> favorites;

  FavoritesViewModel() {
    loadFavorites();
  }

  void deleteFavorite(String id) {
    if (favorites.contains(id)) {
      this.favorites.remove(id);
    }
    Storage.initializeList(kFavoritesKey, favorites);
    notifyListeners();
  }

在详细信息视图(用户可以选择删除收藏夹的地方)中,我得到了对收藏夹视图模型的引用

FavoritesViewModel favesVM = FavoritesViewModel(); // serviceLocator<FavoritesViewModel>();

并从对话框中调用其 deleteFavorite 函数:

var approveRemovalButton = FlatButton(
  child: Text('Remove',
    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue),
  ),
  onPressed: () {
      animationDuration = 0;
      favesVM.deleteFavorite(widget.gaugeId);
      Navigator.pop(context);
  },
);

当我点击一个按钮并在视图模型上调用 deleteFavorite 函数时,该项目将从用户首选项中删除,并且也从视图模型中删除,但是,在返回到收藏夹列表视图时,该项目仍然存在于 UI 中. 就好像收藏夹列表视图没有注册为监听器并且没有响应notifyListeners. 谁能看到可能导致这种情况的原因?谢谢!

标签: androidiosflutterstate

解决方案


您有两个视图模型同时运行的问题,让我解释一下:

通过调用FavoritesViewModel viewModel = FavoritesViewModel(); // serviceLocator<FavoritesViewModel>(); 这将从视图模型中创建一个实例。

而且,通过这样做

ChangeNotifierProvider(
        create: (context) => FavoritesViewModel(),
        child: MyApp(),
      )

您正在创建另一个视图模型

所以棘手的部分是:您有两个包含相同数据的视图模型,您正在使用来自消费者(而不是定位器)的视图模型将数据显示到您的列表视图中,然后您从定位器中删除数据,所以删除不会被反映。

作为一种解决方案,您可以包装FavoriteCardConsumer<FavoritesViewModel>使用model.deleteFavorite()


推荐阅读