Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 在FutureBuilder中设置提供程序值_Flutter_Dart_Flutter Provider - Fatal编程技术网

Flutter 在FutureBuilder中设置提供程序值

Flutter 在FutureBuilder中设置提供程序值,flutter,dart,flutter-provider,Flutter,Dart,Flutter Provider,我有一个小部件,它向返回地图的api发出请求。我想做的不是每次加载小部件时都发出相同的请求,并将列表保存到appState.myList。但是当我这样做时,appState.myList=snapshot.data在FutureBuilder中,我得到以下错误: 颤振:══╡ 基金会例外╞════════════════════════════════════════════════════════ 颤振:在为MySchedule发送通知时引发了以下断言: 颤振:在生成过程中调用setState

我有一个小部件,它向返回地图的api发出请求。我想做的不是每次加载小部件时都发出相同的请求,并将列表保存到
appState.myList
。但是当我这样做时,
appState.myList=snapshot.data
FutureBuilder
中,我得到以下错误:

颤振:══╡ 基金会例外╞════════════════════════════════════════════════════════
颤振:在为MySchedule发送通知时引发了以下断言:
颤振:在生成过程中调用setState()或markNeedsBuild()。
颤振:无法将此ChangeNotifierProvider小部件标记为需要生成,因为
颤振:框架已经在构建小部件的过程中。可以将小部件标记为需要
颤振:仅当其祖先之一当前正在建造时,才在建造阶段建造。。。
sun.dart
文件:

class-Sun扩展了无状态小部件{
小部件构建(构建上下文){
final appState=Provider.of(上下文);
var db=PostDB();
小部件列表构建(appState){
最终列表=appState.myList;
返回ListView.builder(
itemCount:list.length,
itemBuilder:(上下文,索引){
返回ListTile(标题:Text(列表[index].title));
},
);
}
Widget futureBuild(appState){
回归未来建设者(
future:db.getPosts(),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
//appState.myList=snapshot.data;
返回ListView.builder(
itemCount:snapshot.data.length,
itemBuilder:(上下文,索引){
返回ListTile(标题:Text(snapshot.data[index].title));
},
);
}else if(snapshot.hasrerror){
返回文本(“${snapshot.error}”);
}
返回中心(
子对象:CircularProgressIndicator(),
);
},
);
}
返回脚手架(
正文:appState.myList!=null
?列表构建(appState)
:futureBuild(appState));
}
}
postService.dart
文件:

class PostDB{
var isLoading=false;
Future getPosts()异步{
isLoading=true;
最后答复=
等待http.get(“https://jsonplaceholder.typicode.com/posts");
如果(response.statusCode==200){
isLoading=false;
返回(json.decode(response.body)作为列表)
.map((数据)=>Postmodel.fromJson(数据))
.toList();
}否则{
抛出异常(“加载帖子失败”);
}
}
}
我知道
myList
调用
notifyListeners()
,这就是导致错误的原因。希望我没弄错。如果是这样,我如何设置appState.myList并在应用程序中使用而不出现上述错误

导入“包:flift/foundation.dart”;
导入“包:myflatter/models/post model.dart”;
使用ChangeNotifier类MySchedule{
列表(myList),;
List get myList=>\u myList;
设置myList(列出新值){
_myList=新值;
notifyListeners();
}
}

出现该异常是因为您正在同步修改来自其子体的小部件

这是不好的,因为它可能导致不一致的小部件树。一些小部件。可能是使用变异前的值构建小部件,而其他小部件可能使用变异后的值

解决方法是消除不一致性。使用
ChangeNotifierProvider
,通常有两种情况:

  • changennotifier
    上执行的变异总是在创建
    changennotifier
    的版本内执行

    在这种情况下,您可以直接从
    变更通知程序的构造函数执行调用:

    将MyNotifier与ChangeNotifier一起分类{
    MyNotifier(){
    //TODO:启动一些请求
    }
    }
    
  • 执行的更改可能会“延迟”进行(通常在更改页面之后)

    在这种情况下,您应该在
    addPostFrameCallback
    Future中将您的突变包装起来

    类示例扩展了StatefulWidget{
    @凌驾
    _ExampleState createState()=>\u ExampleState();
    }
    类_示例状态扩展状态{
    MyNotifier通知程序;
    @凌驾
    void didChangeDependencies(){
    super.didChangeDependencies();
    final notifier=Provider.of(上下文);
    if(this.notifier!=通知程序){
    this.notifier=通知程序;
    Future.microtask(()=>notifier.doSomeHttpCall());
    }
    }
    @凌驾
    小部件构建(构建上下文){
    返回容器();
    }
    }
    

我在使用提供商时遇到了与您类似的问题。我的解决方案是在获取数据时添加
WidgetsBinding.instance.addPostFrameCallback()

只需删除
notifyListeners()来自代码。我遇到了这个错误,这就是我解决问题所做的。

您在哪里使用setter for
myList
?在FutureBuilder中<代码>如果(snapshot.hasData){//appState.myList=snapshot.data;
为什么不在
getPosts
中呢?是的……那会更好……但是我能拥有
final appState=Provider.of(上下文)吗
在那里?我没有上下文…我从来没有真正理解
上下文
的作用。我是个新手。请发布一个答案。我不知道,我没有
提供者
类的经验。这个解决方案很好。我以为OP只想加载一次。在这种情况下,
变更通知者
似乎不合适并使用
Future.microtask
build
中退出调用
setState