koin icon indicating copy to clipboard operation
koin copied to clipboard

Different viewModel instances based on the different input params in the same ViewModelStoreOwner[JetpackCompose]

Open PavloZoria opened this issue 3 years ago • 5 comments

Is your feature request related to a problem? Please describe. Preconditions:

  • Koin version: 3.1.2
  • jetpackCompose version: 1.0.0-rc01

I have the next situation: I'm using the Koin with a JetpackCompose and here I have com.google.accompanist.pager.HorizontalPager(it is equal to the ViewPager). Each page of the viewPager loads data based on the title: image On the screen above my title would be: "Macros" and "Factors". These titles are dynamic and can be any values so I can't just declare named dependency in the koin module. Each of the pages should contain the same ViewModel but with different parameters. Params is a title from viewPager( "Macros" or "Factors") and the content of these pages will be different based on these params.

Describe the solution you'd like An easier solution that I see here is to calculate the hashCode of params and add it to the key when we register an instance of our ViewModel to ViewModelProvider and retrieve values from ViewModelProvider with this hashCode in key accordingly.

Note: I can't use qualifiers in this case because Koin combine qualifier with class full name in indexKey(clazz, qualifier, scopeQualifier) method before _instances[indexKey]?.get(instanceContext) as? T (InstanceRegistry.resolveInstance) and I can't get instance because dependency with this key was not registered

Target Koin project Koin for JetpackCompose implementation "io.insert-koin:koin-androidx-compose:$koin_version"

PavloZoria avatar Jul 07 '21 12:07 PavloZoria

Would implementing it with scopes work? Basically, you define a custom Koin scope whose type is some class associated with the Page Composable, and which is a KoinScopeComponent, which allows you to call createScope, and the view models will be bound to the scope. So you wouldn't be binding the lifecycle of your view models to the texts/titles, but rather the pages that they represent. In the composables you would remember an instance of this type, use it to create the scope, and use that to get the view models from.

wujek-srujek avatar Sep 14 '21 22:09 wujek-srujek

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Mar 23 '22 09:03 stale[bot]

@PavloZoria were you able to implement this with custom scope? If, so: do you have any pointers? I am running into the same problem.

NielsMasdorp avatar Mar 30 '22 13:03 NielsMasdorp

@PavloZoria @NielsMasdorp Were either of you able to implement this in the end?

I'm looking at something similar, with a horizontal pager of items in Jetpack Compose, each backed by a view model that I need to pass a parameter to

sebj avatar May 30 '22 09:05 sebj

@PavloZoria @NielsMasdorp Were either of you able to implement this in the end?

I'm looking at something similar, with a horizontal pager of items in Jetpack Compose, each backed by a view model that I need to pass a parameter to

I just used ViewModeFactory and there I put different params. The viewModel was created using a native creator. You can provide ViewModelFactory using koin in case you strive to use DI in any case cc @NielsMasdorp

PavloZoria avatar May 30 '22 09:05 PavloZoria

duplicate with #1305

arnaudgiuliani avatar Aug 29 '22 15:08 arnaudgiuliani

Is ViewModel the right component here? Why not use a factory for such new objects?

arnaudgiuliani avatar Sep 07 '22 09:09 arnaudgiuliani

Is ViewModel the right component here? Why not use a factory for such new objects?

Do you mean that approach? https://github.com/InsertKoinIO/koin/issues/1142#issuecomment-1140925601

PavloZoria avatar Oct 21 '22 11:10 PavloZoria