flutter [go_router] Run GoRouteData.redirect with the BuildContext of the containing ShellRoute

xoefb8l8  于 2个月前  发布在  Flutter
关注(0)|答案(7)|浏览(31)

用例

我有一个 ShellRoute ,以及一个 MyShell 小部件,它引入了一些针对该 MyShell 的范围。MyShell 中可能有任意状态、数据获取、缓存等。
对于一个 GoRouteData ,它是包含 TypedGoRouteTypedShellRouteredirect ,我希望能够编写一个 redirect ,使其利用 Shell 的提供者,而不是将这些提供者提升到整个路由器之上。

建议

不要像下面这样使用树形结构:

  • Provider
  • State
  • Router
  • Shell
  • 通过提供者/状态重定向

让我写:

  • Router
  • Shell
  • Provider
  • State
  • 通过提供者/状态重定向
az31mfrm

az31mfrm1#

你好,@aran,你能分享一个例子以及实际/预期的结果吗?这样使用案例会更清晰。

jxct1oxe

jxct1oxe2#

这是一个不起作用的代码示例,我认为可能有必要提供一种使其起作用的方法: aran/flutter-shell-redirect@5a5ed14

xkftehaa

xkftehaa3#

感谢您的更新。在运行your sample project时,我得到了以下错误,这可能为使用案例提供了详细信息。将问题标记以供进一步调查。
样本代码的输出日志

Launching lib/main.dart on RMX2001 in debug mode...
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
Connecting to VM Service at ws://127.0.0.1:49955/dBO6hMwP7VQ=/ws
I/_shell_redirec(24033): ProcessProfilingInfo new_methods=1071 is saved saved_to_disk=1 resolve_classes_delay=5000
I/_shell_redirec(24033): Compiler allocated 4670KB to compile void android.view.ViewRootImpl.performTraversals()
E/ion     (24033): ioctl c0044901 failed with code -1: Invalid argument
D/ViewRootImpl(24033): enqueueInputEventMotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=457.0, y[0]=1176.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=120445244, downTime=120445244, deviceId=3, source=0x1002, displayId=0 }
D/ViewRootImpl[MainActivity](24033): processMotionEvent MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=457.0, y[0]=1176.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=120445244, downTime=120445244, deviceId=3, source=0x1002, displayId=0 }
D/ViewRootImpl[MainActivity](24033): dispatchPointerEvent handled=true, event=MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=457.0, y[0]=1176.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=120445244, downTime=120445244, deviceId=3, source=0x1002, displayId=0 }
D/ViewRootImpl[MainActivity](24033): processMotionEvent MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=457.0, y[0]=1176.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=120445370, downTime=120445244, deviceId=3, source=0x1002, displayId=0 }
D/ViewRootImpl[MainActivity](24033): dispatchPointerEvent handled=true, event=MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=457.0, y[0]=1176.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=120445370, downTime=120445244, deviceId=3, source=0x1002, displayId=0 }
E/flutter (24033): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Error: Could not find the correct Provider<ExpensiveOnboardingData> above this Router<Object> Widget
E/flutter (24033):
E/flutter (24033): This happens because you used a `BuildContext` that does not include the provider
E/flutter (24033): of your choice. There are a few common scenarios:
E/flutter (24033):
E/flutter (24033): - You added a new provider in your `main.dart` and performed a hot-reload.
E/flutter (24033):   To fix, perform a hot-restart.
E/flutter (24033):
E/flutter (24033): - The provider you are trying to read is in a different route.
E/flutter (24033):
E/flutter (24033):   Providers are "scoped". So if you insert of provider inside a route, then
E/flutter (24033):   other routes will not be able to access that provider.
E/flutter (24033):
E/flutter (24033): - You used a `BuildContext` that is an ancestor of the provider you are trying to read.
E/flutter (24033):
E/flutter (24033):   Make sure that Router<Object> is under your MultiProvider/Provider<ExpensiveOnboardingData>.
E/flutter (24033):   This usually happens when you are creating a provider and trying to read it immediately.
E/flutter (24033):
E/flutter (24033):   For example, instead of:
E/flutter (24033):
E/flutter (24033):   ```
E/flutter (24033):   Widget build(BuildContext context) {
E/flutter (24033):     return Provider<Example>(
E/flutter (24033):       create: (_) => Example(),
E/flutter (24033):       // Will throw a ProviderNotFoundError, because `context` is associated
E/flutter (24033):       // to the widget that is the parent of `Provider<Example>`
E/flutter (24033):       child: Text(context.watch<Example>().toString()),
E/flutter (24033):     );
E/flutter (24033):   }
E/flutter (24033):   ```
E/flutter (24033):
E/flutter (24033):   consider using `builder` like so:
E/flutter (24033):
E/flutter (24033):   ```
E/flutter (24033):   Widget build(BuildContext context) {
E/flutter (24033):     return Provider<Example>(
E/flutter (24033):       create: (_) => Example(),
E/flutter (24033):       // we use `builder` to obtain a new `BuildContext` that has access to the provider
E/flutter (24033):       builder: (context, child) {
E/flutter (24033):         // No longer throws
E/flutter (24033):         return Text(context.watch<Example>().toString());
E/flutter (24033):       }
E/flutter (24033):     );
E/flutter (24033):   }
E/flutter (24033):   ```
E/flutter (24033):
E/flutter (24033): If none of these solutions work, consider asking for help on StackOverflow:
E/flutter (24033): https://stackoverflow.com/questions/tagged/flutter
E/flutter (24033):
E/flutter (24033): #0      Provider._inheritedElementOf (package:provider/src/provider.dart:343:7)
E/flutter (24033): #1      Provider.of (package:provider/src/provider.dart:293:30)
E/flutter (24033): #2      ReadContext.read (package:provider/src/provider.dart:649:21)
E/flutter (24033): #3      OnboardingFirstScreenRoute.redirect (package:flutter_shell_redirect/routes/main_router.dart:49:23)
E/flutter (24033): #4      GoRouteData.$route.redirect (package:go_router/src/route_data.dart:107:28)
E/flutter (24033): #5      RouteConfiguration._getRouteLevelRedirect (package:go_router/src/configuration.dart:451:44)
E/flutter (24033): #6      RouteConfiguration.redirect.processRedirect.processTopLevelRedirect (package:go_router/src/configuration.dart:406:13)
E/flutter (24033): #7      RouteConfiguration.redirect.processRedirect (package:go_router/src/configuration.dart:423:16)
E/flutter (24033): #8      RouteConfiguration.redirect (package:go_router/src/configuration.dart:429:14)
E/flutter (24033): #9      GoRouteInformationParser._redirect (package:go_router/src/parser.dart:169:10)
E/flutter (24033): #10     GoRouteInformationParser.parseRouteInformationWithDependencies (package:go_router/src/parser.dart:104:32)
E/flutter (24033): #11     _RouterState._processRouteInformation (package:flutter/src/widgets/router.dart:749:8)
E/flutter (24033): #12     _RouterState._handleRouteInformationProviderNotification (package:flutter/src/widgets/router.dart:767:5)
E/flutter (24033): #13     ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:433:24)
E/flutter (24033): #14     GoRouteInformationProvider.notifyListeners (package:go_router/src/information_provider.dart:134:11)
E/flutter (24033): #15     GoRouteInformationProvider._setValue (package:go_router/src/information_provider.dart:144:7)
E/flutter (24033): #16     GoRouteInformationProvider.go (package:go_router/src/information_provider.dart:166:5)
E/flutter (24033): #17     GoRouter.go (package:go_router/src/router.dart:340:30)
E/flutter (24033): #18     GoRouterHelper.go (package:go_router/src/misc/extensions.dart:25:25)
E/flutter (24033): #19     $OnboardingFirstScreenRouteExtension.go (package:flutter_shell_redirect/routes/main_router.g.dart:63:44)
E/flutter (24033): #20     MyHomePage.build.<anonymous closure> (package:flutter_shell_redirect/screens/my_home_page.dart:19:48)
E/flutter (24033): #21     _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1183:21)
E/flutter (24033): #22     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:315:24)
E/flutter (24033): #23     TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:652:11)
E/flutter (24033): #24     BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:309:5)
E/flutter (24033): #25     BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:242:7)
E/flutter (24033): #26     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:670:9)
E/flutter (24033): #27     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
E/flutter (24033): #28     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
E/flutter (24033): #29     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)
E/flutter (24033): #30     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
E/flutter (24033): #31     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
E/flutter (24033): #32     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:495:19)
E/flutter (24033): #33     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:475:22)
E/flutter (24033): #34     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:430:11)
E/flutter (24033): #35     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:420:7)
E/flutter (24033): #36     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:383:5)
E/flutter (24033): #37     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:330:7)
E/flutter (24033): #38     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:299:9)
E/flutter (24033): #39     _invoke1 (dart:ui/hooks.dart:328:13)
E/flutter (24033): #40     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:429:7)
E/flutter (24033): #41     _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)
E/flutter (24033):
<inspected variable>
Lost connection to device.

Exited.
vulvrdjw

vulvrdjw4#

确认错误是故意/预期的。功能请求是进行框架更改,以使代码运行(或提供其他支持机制来实现相同的基本目标)

cgh8pdjw

cgh8pdjw5#

这是我今天发现的一件事。如果能修复它就太好了。我的用例是使用Bloc模式 - 我希望有一个Bloc,我只能在页面的子集(在重定向回调中)上使用shell路由,但目前这是不可能的。

pw136qt2

pw136qt26#

当你进行重定向时,你期望在当前的小部件树中访问提供者还是在新导航后的新的小部件树中访问提供者?

yqhsw0fo

yqhsw0fo7#

在我们的情况下,至少我们通常在同一个 shell 内导航到另一个路线,所以我们希望提供者在新的小部件树中保持稳定。示例项目重定向显示了这种模式。

相关问题