我想解决的问题:使用GoRouter的应用程序需要能够从main()内路由到指定的路由。由于大多数路由都是'context.go‘形式的,所以我不能在main中这样做。
背景
我的应用程序使用GoRouter。GetX让我定义命名的路由并从main()传递参数是非常容易的。
然而,GetX和GoRouter最终给我带来了问题。GoRouter最终将在应用程序的其他部分没有上下文。
如果有办法让它们简单地共存,我就会敞开心扉。
我在GetIt包中使用了服务定位器模式来与navigatorKey相关联。当我测试它时,它会起作用--但这涉及到创建两个MaterialApps。
然而,这个应用程序使用的是GoRouter,它似乎不使用navigatorKey。
我想从main ()内部走一条具体的路线。服务定位器模式似乎可以像在Navigator2.0中用于GoRouter那样适用于MaterialApp --但我找不到如何这样做的示例。
更详细的上下文:
以下是我目前在main()中的内容。
您可以看到我面临的关键挑战是,数据参数的侦听器在主生命中传递(我是从第三方SDK获得的--我不需要它在main中,但是不管应用程序的状态如何,它都需要侦听)。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FFAppState(); // Initialize FFAppState
GetSocial.addOnInitializedListener(() => {
// GetSocial SDK is ready to use
});
setupLocator();
runApp(MyApp());
locator<LandingPageData>().referralID = "defaultReferralID";
registerListeners();
}
void registerListeners() {
Invites.setOnReferralDataReceivedListener((received) {
globalReferralData = received;
print(globalReferralData);
print(globalReferralData.linkParams);
print("listener - socialdata");
String passedReferralID =
globalReferralData.linkParams['referralID'].toString();
String passedCreatorID =
globalReferralData.linkParams['creatorID'].toString();
String passedCampaignID =
globalReferralData.linkParams['\$campaign_id'].toString();
print(passedReferralID);
print(passedCreatorID);
print(passedCampaignID);
// How can I route to a named Route?
locator<LandingPageData>().referralID = passedReferralID;
locator<LandingPageData>().creatorID = passedCreatorID;
locator<LandingPageData>().campaignID = passedCampaignID;
});
}下面是locator.service.dart的样子:
final locator = GetIt.instance;
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// final GlobalKey<ScaffoldMessengerState> navigatorKey = GlobalKey<ScaffoldMessengerState>();
}当我可以附加到一个navigatorKey,然后从侦听器中导航时,上面的内容就起作用了。但这似乎不起作用,因为应用程序的其余部分使用GoRouter。
发布于 2022-07-25 10:37:52
不幸的是,如果我是你,我要么放弃使用GetX或GoRouter。
实际上,我会放弃GetX。
原因是GetX在引擎盖下执行了魔法,这提高了开发人员对BuildContext的责任和使用能力,但这显然是一种反模式,因为Flutter内置的导航显然使用了context:例如,想想Navigator.of。
GoRouter是围绕context构建的,它简化了执行“Navigator2.0”操作所需的许多实现。
如果您试图实现深度链接,那么您的MaterialApp在根小部件中应该如下所示:
return MaterialApp.router( // Flutter's Router 2.0 usage
title: 'MyApp',
routeInformationProvider: myGoRouter.routeInformationProvider,
routeInformationParser: myGoRouter.routeInformationParser,
routerDelegate: myGoRouter.routerDelegate,
);如果GetX使您能够将myGoRouter放在那里,那么您应该是好的。但正如我前面所说,每次需要显式导航时,都需要上下文。
发布于 2022-09-03 18:03:15
我正在研究在我的项目中采用go_router,而且我也对这个使用过程感到困惑(在我的例子中,我试图证明我可以从appsflyer的回调延迟链接中导航)。
对于解决方案,像这样的go_router允许我们从路由器声明下面的上下文或者从重定向状态导航。因此,我们可以结束所有影响导航的状态。我就是这样从appRouterState重定向的
redirect: (GoRouterState state) {
String? redirection(GoRouterState state) {
final appRouterState = ref.read(appRouterStateNotifierProvider);
final isAuthed = appRouterState.email != null;
if (appRouterState.deferredLink != state.location && appRouterState.deferredLink != null) {
return appRouterState.deferredLink;
}
if (state.location != '/login' && !isAuthed) return '/login';
if (state.location == '/login' && isAuthed) return '/';
return null;
}
final result = redirection(state);
return result;
},在您的例子中,您可以在setOnReferralDataReceivedListener或其他方面实现appRouterStateProvider。并将其用于refreshListenable构造函数中的GoRouter参数。
希望这能有所帮助。
发布于 2022-09-29 07:47:47
static BuildContext? get ctx => myGoRouter.routerDelegate.navigatorKey.currentContext;您可以以这种方式在NavigationService中获取上下文,并将其使用如下
NavigationService.ctx?.go(...)您可能面临的问题是,在应用程序状态下ctx将为空,直到您的第一页开始构建。如果您的侦听器有一个数据,而ctx仍然是空的,则路由将无法工作。但你可以像这样:
在主功能或服务中定义全局tempPageToGo,并且
var _ctx = NavigationService.ctx;
if(_ctx == null) {
tempPageToGo = anyPageDataYouWant;
while((await Future.delayed(Duration(seconds: 1))) == null) {
if(_ctx != null) {
_ctx!.go(...);
break;
}
}
} else _ctx!.go(...);https://stackoverflow.com/questions/73059450
复制相似问题