Just made `koinNavGraphViewModel()` function to sc...
# koin-contributors
a
Just made
koinNavGraphViewModel()
function to scope a ViewModel to a given Nav Graph
@Nacho Ruiz Martin it will be ok for Koin 3.1.3
I will integrate your sample in the koin android sample app đź‘Ť
n
Awesome, man. Thanks for that!
a
thanks for your help
🙇 1
n
Hey, @arnaud.giuliani man! 👋 I don’t know if you’re aware, but this is not compatible with the current way to use Nav Graphs in Compose. When using Compose, you don’t have
.xml
graph files, nor graph IDs. I have a proposal for a modification of the current
getViewModel
Composable function to be able to pass the
ViewModelStoreOwner
. Since
NavBackStackEntry
implements the interface (doc) it would be easy to use. You can see the proposal in this gist: https://gist.github.com/iruizmar/e15c89e6cbe868f3633facbd4cd313cc ⚠️ It’s not tested in depth, this is just a draft proposal.
a
you mean, opening to have
viewModelStoreOwner: ViewModelStoreOwner = LocalViewModelStoreOwner.current!!,
inside the
getViewModel
?
n
Yes 🙂 That’s the exact change. As you can see, you can then provide a different
ViewModelStoreOwner
such as a
NavBackStackEntry
and the
ViewModel
scope will be attached to that one.
That’s really useful to scope it to a subgraph in compose, which is basically represented as a
NavBackStackEntry
. Here’s how Hilt is doing it (similar way): https://developer.android.com/jetpack/compose/libraries?#hilt-navigation
🤔 Maybe I could apply this to the sample I sent you for you to see it in action?
@arnaud.giuliani đź‘‹ I updated the toy app with this new usage. Maybe this way, it will clarify the needing. https://github.com/iruizmar/koin-nav-compose-toy/commit/488122ff103fc2e879a03516476535e0b46c32b7
a
great, let me check đź‘Ť
we could squash usage of `
Copy code
val parentEntry = remember {
                    navController.getBackStackEntry("bc")
                }
                ScreenB(
                    viewModel = getViewModel(parentEntry),
                    navigateToA = { navController.navigate("a") },
                    navigateToC =  { navController.navigate("c") }
                )
to something like
getNavGraphViewModel("bc")
directly
n
You'd need the NavController inside the
getNavGraphViewModel
for that, though.
a
yes, we could do that inside
n
I don’t understand where will we get the NavController from. It should be provided from the root of the NavGraph. So the API would look like:
getNavGraphViewModel("bc", navController)
Is that good enough?
a
I see, you need to have your navController on your side. Let me check again 🤔
đź‘Ť 1
then it’s working with the current ViewModel API then?
n
It is working if you want to have a ViewModel scoped to a single destination of the graph, for example like ViewModelA in the toy app: line. But if you want to have a ViewModel scoped to a subgraph, for example ViewModelBC that should be scoped to the graph with route “bc” in the toy app it’s not working. And it is not working because the current API always gets the ViewModelOwner from
LocalViewModelStoreOwner.current
which happens to be the current destination on the graph. So if you use the current API from composableB, you’ll get a ViewModel that will live while you are inside that destination. You can’t have a ViewModel attached to a subgraph (shared between B and C, in other words). And that is what fixes my approach, by letting the user to provide it with a different owner, in this case:
navController.getBackStackEntry("bc")
a
yes, need to allow to use the right store 🤔
n
I can open a PR with the little change on the Composable
getViewModel
, is that OK?
a
I’ve pushed this - d77fcc482126b79d943ea11ddf5befa2369ef0bb
tell me what you think đź‘Ť
n
Awesome đź’Ş
Hey @arnaud.giuliani! Sorry to come back with this topic again, but currently, 3.1.4's
getViewModel
expects a
ViewModelOwner
and Navigation’s
NavStackEntry
are actually `ViewModelStoreOwner`s . This makes the way to use the API uglier, like this:
Copy code
getViewModel(owner = ViewModelOwner.from(parentEntry))
I don’t know the real difference between
ViewModelOwner
and
ViewModelStoreOwner
. Is there any reason for you to be using the first one?
a
ViewModelOwner is more there to let choose ViewModelStoreOwner or RegistryOwner
let see how to simplify then
n
A simple overload of the
getViewModel
method would suffice. If you provide a
ViewModelStoreOwner
then Koin will use
ViewModelOwner.from
to get a
ViewModelOwner
. WDYT?
a
yes, was thinking about something like that yes
I will make a PR. I’ll ping you
161 Views