customValue support for VNester and route elements #176
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This enhancement is motivated by the code example here from #32 to use
VNester
and sync bottom nav bar and nested tab bar with routes while preserving state.While the code example from the linked comment above works, you have to repeat the whole
VNester
and thewidgetBuilder
(only varying thecurrentIndex
in the constructor to the widget). This gets pretty cumbersome if you have more complex nested routes withVGuard
or as the nesting level goes 3-deep in a more complex app.The reason why the whole
VNester
has to be repeated in the example is that there is no way to associate with the child widget the tab index (even a mixin to Widget won't work, as the actual child widget is wrapped in aBuilder
and cannot be accessed directly from thechild
parameter passed to thewidgetBuilder
function).This PR adds the concept of an optional
customValue
dynamic value toVRouteElement
, and then an optional second type ofwidgetBuilder
that will take(child, customValue)
instead of just(child)
.VNester
is enhanced to then search for and provide the "nearest" customValue on the matched route to the child to thewidgetBuilder
(logic to do this only happens ifwidgetBuilder
has the new type -- the old type is still accepted for backwards compatibility as well). This simplifies the code example to the following:Show modified "advanced" example that uses `customValue`
However, it is causing an issue where after navigating back and forth between different nested routes now that there is only a single VNester, flutter (2.8.0) throws the error:
(Note that there is a RenderIndexedStack exception getting thrown sometimes too, but that wasn't happening in the full-scale app, it was just the Duplicate GlobalKey exception that was occurring whenever changing the route to a different tab at the same "nesting level" as the current route.)
And inspecting the debug label of the
GlobalKey
, it is the global key of the top-most level VNester. Using multiple VNesters like the original example (even with customValue) doesn't have this problem, so it doesn't seem like the customValue changes cause this directly, but it might be something unexpected with how this is working now that only a single VNester is needed at each level. I'm not a flutter expert (yet!), and so was hoping @lulupointu you might have some insights why this might be happening / how to fix it.I'd also love your feedback on the general direction of this PR as well! At first I tried to add a custom value chain (similar to name) in
VRoute
, but this was complex and also was difficult to know exactly which customValue should be passed towidgetBuilder
(especially when there are multiple nested VNester). This PR is the second attempt that is simpler where it just searches the element list (which does have only the list of child route elements at the point of VNester, so it was both simpler and worked with all levels of nesting).In the meantime, I made a custom
VRouteElementBuilder
that generates the multipleVNester
(one for each tab) so that it removes boilerplate / duplicate code, and still works with the current vRouter as released. In case it's useful to anyone:Show code for TabbedNester