routemaster
routemaster copied to clipboard
Wrapping a specific set of routes
Hey Tom
Super cool package! The dynamic route map based on state is a new idea I haven't really seen before , but I really like it
I couldn't find this in the examples, but I was wondering if there is a way to wrap a specific set of routes with other widgets.
an application of this would be to wrap all /groups routes with a GroupsBloc
Thanks~
Thank you! Just to confirm - this would be to inject an object, something like this pseudocode?
RouteMap(
routes: {
'/': (_) => MaterialPage(child: HomePage()),
ChangeNotifierProvider(
create: (_) => GroupsBloc(),
routes: {
'/group': (_) => MaterialPage(child: GroupPage()),
// More routes
}
),
},
)
I've got some thoughts about groups of routes, but nothing implemented yet.
Yep!
Do you have a specific example of why this would be useful, and why you wouldn't just wrap all the routes in the provider?
For me at least - i like to scope Bloc only to the routes that need them. For example, I would only want to scope my
GroupsBloc
to all routes that start with /groups
Cool, I think it would be especially useful to teams in large apps if they could make a modular group of routes with their own set of injected dependencies.
Also, by wrapping things, we could achieve something that VRouter does with
VNester
- you could have a persistent appbar or whatever widget you want that always shows and does not get re-rendered, and then the rest of the screen would change based on the URL
I'll have a think about this...
Cool update! The TabPage
component looks really cool -
I think the TabPage
is pretty close to what this issue is asking for. The only difference would be that the /feed and /settings routes would also have actual pages associated with them too.
'/': (route) => TabPage(
child: HomePage(), // can define Bloc in here to scope Bloc only to children
paths: [
'/feed', // FeedPage()
'/settings', // SettingsPage()
],
),
But I just realized something - if you create a WrapperPage
that wraps a bunch of routes like this, what happens if you want to Guard a wrapped route based on the local Bloc? It seems like you can only use the context defined in the RouteMasterDelegate
to guard routes currently
This sounds related to https://github.com/tomgilder/routemaster/issues/4. Using the example that you have defined there, I wonder if this could be solved by allowing RouteMap to accept a builder @tomgilder.
final masterRouteMap = RouteMap(routes: {
...teamOneMap.routes,
...teamTwoMap.routes,
});
final teamOneMap = RouteMap(
routes: {
'/app-section-one': (_) => TeamOnePage(),
},
);
final teamTwoMap = RouteMap(
builder: (context, child) => ChangeNotifierProvider(
create: (_) => GroupsBloc(),
child: child,
),
routes: {
'/app-section-two': (_) => TeamTwoPage(),
},
);
You can pretty much do this currently without any chances to Routemaster.
And yes, I barely understand BuilderRouteMap
despite just typing it myself 😁
final teamOneMap = BuilderRouteMap(
builder: (builder) {
return MaterialPage<void>(
child: ChangeNotifierProvider(
create: (context) => AppState(),
child: Builder(builder: builder),
),
);
},
widgetRoutes: {
'/one': (routeData, context) => Container(
child: Text(Provider.of<AppState>(context).message),
),
},
);
final routeMap = RouteMap(
routes: {
'/': (routeData) => MaterialPage(child: Text('Hello world')),
...teamOneMap.routes,
},
);
class BuilderRouteMap extends DefaultRouterConfig {
BuilderRouteMap({
required MaterialPage Function(Widget Function(BuildContext)) builder,
required Map<String, Widget Function(RouteData, BuildContext)> widgetRoutes,
}) : routes = widgetRoutes.map(
(key, widgetBuilder) => MapEntry(
key,
(routeData) => builder(
(context) => widgetBuilder(routeData, context),
),
),
);
@override
final Map<String, PageBuilder> routes;
}
The only downside is that from within teamOneMap
you wouldn't be able to use the special "pages" like Redirect()
, but that's just an API tradeoff sadly.