首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dispose后返回未来

dispose后返回未来
EN

Stack Overflow用户
提问于 2021-10-07 10:19:41
回答 1查看 32关注 0票数 1

当api调用返回时,我需要显示一个快餐栏。问题是我在api调用完成之前就弹出了路由。因此,我得到以下错误:

代码语言:javascript
复制
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

这是我的代码:

代码语言:javascript
复制
ElevatedButton(
  onPressed: () async {

    final snackBar = SnackBar(
      behavior: SnackBarBehavior.fixed,
      duration: Duration(seconds: 2),
      content: Text('Done'),
    );

    apiCall().whenComplete(() => ScaffoldMessenger.of(context).showSnackBar(snackBar));
    Navigator.pop(context);
  },
  child: Text('Fetch data'),
),

路由弹出后,api调用完成,如何显示快餐栏?

EN

回答 1

Stack Overflow用户

发布于 2021-10-07 11:31:43

有几个选项可以做到这一点。最简单的方法可能是保持当前屏幕不动,直到按下API键,并显示某种操作正在进行中的指示(即CircularProgressIndicator)。下一个最简单的方法是从调用此按钮的页面进行API调用-即在该页面中,当您调用Navigator.push(...)时,您可以改为执行let shouldDoCall = await Navigator.push(...),然后执行if (shouldDoCall == true) apiCall()...,最后,在您的ElevatedButton的on-pressed中,如果按钮被按下,您可以执行Navigator.pop(context, true);,否则执行false。

如果这两者都不是一个选项,你可能会想要实现某种api控制器/管理器来负责这些长时间的网络请求-尽管这将变得更加复杂。

我可以给你一个非常快速的概述来实现它,但是实际的代码可能超出了这个问题的范围。使用像Provider这样的东西,您可以拥有一个位于导航器上方的树中的高级ApiController模型。您将能够从任何页面访问它,并触发请求。在每个能够显示消息的页面中,您可以在页面的initState中从相同的控制器订阅事件流,并在dispose方法中取消订阅。如果你想变得更花哨,你甚至可以让事件排队,而不只是一个哑流,这意味着每当页面下一次订阅时,他们将接收任何排队等待显示但实际上还没有显示的事件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69479429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档