如何解决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(),)
);
});
}
我的ListView
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函数时,该项目从用户首选项中删除,并且也从视图模型中删除,但是,返回到收藏夹列表视图后,该项目仍然存在在用户界面中。就像“收藏夹”列表视图没有注册为侦听器,并且不响应notifyListeners
。谁能看到是什么原因造成的?谢谢!
解决方法
您有两个视图模型同时运行的问题,让我解释一下:
通过致电FavoritesViewModel viewModel = FavoritesViewModel(); // serviceLocator<FavoritesViewModel>();
这将从视图模型创建一个实例。
还有,通过这样做
ChangeNotifierProvider(
create: (context) => FavoritesViewModel(),child: MyApp(),)
您正在创建另一个视图模型
所以棘手的是:您有两个视图模型都包含相同的数据, 您正在使用使用者(而不是定位器)的视图模型将数据显示到列表视图中,然后从定位器中删除数据,因此删除不会反映出来。
作为解决方案,您可以用FavoriteCard
包裹Consumer<FavoritesViewModel>
并使用model.deleteFavorite()
我认为您正在显式创建多个提供,并且已将数据加载到一个提供程序中,当您通知更改时,父通知者会收到通知,更改不会得到反映。不要创建单独的FavoritesViewModel
,因为您应该使用同一对象。您已经在runApp()
请替换
FavoritesViewModel viewModel = FavoritesViewModel();
使用
FavoritesViewModel viewModel = Provider.of<FavoritesViewModel>(context);
,
像下面这样更新您的State<FavoritesView>
:
class _FavoritesView extends State<FavoritesView> {
FavoritesViewModel viewModel;
@override
void initState() {
super.initState();
viewModel = Provider.of<FavoritesViewModel>(context,listen: false);
viewModel.loadFavorites();
}
@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]));
},);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。