我想使用 go_router 包打开一个页面并获取返回结果。 在 Navigation 1.0 中,我使用以下代码:
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondRoute()),
);
// handle result
但是我似乎无法使用 go_router 来完成。 有解决方案或解释吗?
我想使用 go_router 包打开一个页面并获取返回结果。 在 Navigation 1.0 中,我使用以下代码:
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondRoute()),
);
// handle result
但是我似乎无法使用 go_router 来完成。 有解决方案或解释吗?
最新版本的go_router包现在支持此功能。 要在从屏幕弹出时传递数据,您可以这样做:
context.pop('value');
为了获取这个值,你的代码应该像这样:
String? val = await context.pushNamed('secondRoute');
GoRouter.of(context).addListener
来完成这个操作。GoRouter.of(context).push("/page/${page!.id}/edit");
GoRouter.of(context).addListener(watchRouteChange);
watchRouteChange() {
if (!GoRouter.of(context).location.contains("/edit")) { // Here you check for some changes in your route that indicate you are no longer on the page you have pushed before
// do something
GoRouter.of(context).removeListener(watchRouteChange); // remove listener
}
}
目前,使用go_router
无法实现此功能。您可以使用go_router_flow
,它与go_router
完全相同,并具有这个带值弹出的特性。
final bool? result = await context.push<bool>('/page2');
WidgetsBinding.instance.addPostFrameCallback((_) {
if(result){
print('Page returned $result');
}
});
当推送新屏幕时,您可以通过将函数放在额外对象中来使用回调。
示例 屏幕A -推送-> 屏幕B ->带结果弹出-> 屏幕A(获取结果)
typedef AddNewEventResult = void Function(Result result);
GoRoute(
path: kScreenB,
builder: (BuildContext context, GoRouterState state) => ScreenB(addNewEventResultstate.extra! as AddNewEventResult),
)
Navigator.of(context).pop();
widget.addNewEventResult(true, Result());
GoRouter(
initialLocation: "/",
routes: <RouteBase>[
GoRoute(
path: "/second",
builder: (_, state) {
final params = state.extra! as SecondPageParams;
return SecondPage(params: params);
},
),
],
);
SecondPage
定义类似于:class SecondPageParams {
final void Function(String data) action;
const SecondPageParams(this.action);
}
class SecondPage extends StatelessWidget {
final SecondPageParams params;
const SecondPage({super.key, required this.params});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: ElevatedButton(
onPressed: () {
context.pop();
params.action("Data from second page");
},
child: const Text("Pop and perform action")
),
),
),
);
}
}
await
context.push
那样简洁明了,但这是一种简单的方法,你可以指定当SecondPage
从堆栈中弹出时要执行的操作,而无需依赖于其他包。onTap: () {
final bool? result = await context.push<bool>('/page2');
if(result ?? false)...
}
返回一个值:
onTap: () => context.pop(true)
截至回答时间,仅支持执行
List<Archive> selectArchives = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const ArchiveListPage(
selectMode: true, canSelectCount: 1)));
context.pop(_selectArchives);
这个流程在文档中描述如下:https://gorouter.dev/user-input
通常情况下,您需要更新数据并返回一些值作为带参数的路由,屏幕本身应该管理更新/数据操作。
我不想在这里复制粘贴他们的代码,但你要找的答案在上面的文档页面中。
使用存档链接进行更新:https://web.archive.org/web/20220325235726/https://gorouter.dev/user-input
感谢 ahmetakil
如果你使用Gorouter,你可以使用
GoRouter.of(context).pop();
当你完成下一个屏幕后,只需使用Navigator.pop(context, true);
,其中true
是你想发送到前一个屏幕的内容。你可以发送任何东西,我只是用true作为参考。这将允许你的result
变量获取数据并执行任何操作。