¿Cómo podemos pasar el parámetro a viewModel en jetpack componer?
este es mi componible
@Composable fun UsersList() { val myViewModel: MyViewModel = viewModel("db2name") // pass param like this }este es el modelo de vista
class MyViewModel(private val dbname) : ViewModel() { private val users: MutableLiveData<List<User>> by lazy { MutableLiveData<List<User>>().also { loadUsers() } } fun getUsers(): LiveData<List<User>> { return users } private fun loadUsers() { // Do an asynchronous operation to fetch users. } }Aquí hay una sintaxis específica de Jetpack Compose/Kotlin para implementar lo mismo:
ui/settings/SettingsViewModel.kt
class SettingsViewModel( private val settingsRepository: SettingsRepository ) : ViewModel() { /* Your implementation */ } class SettingsViewModelFactory( private val settingsRepository: SettingsRepository ) : ViewModelProvider.Factory { override fun <T : ViewModel> create( modelClass: Class<T> ): T { if( modelClass.isAssignableFrom( SettingsViewModel::class.java ) ) { @Suppress( "UNCHECKED_CAST" ) return SettingsViewModel( settingsRepository ) as T } throw IllegalArgumentException( "Unknown ViewModel Class" ) } }Luego:
MainActivity.kt
/* dataStore by preferencesDataStore */ class MainActivity : ComponentActivity() { private lateinit var settingsRepository: SettingsRepository // Here we instantiate our ViewModel leveraging delegates and // a trailing lambda private val settingsViewModel by viewModels<SettingsViewModel> { SettingsViewModelFactory( settingsRepository ) } /* onCreate -> setContent -> etc */ }Como lo mencionó @Secret Keeper, necesita crear una fábrica.
Si su ViewModel tiene dependencias, viewModel() toma un ViewModelProvider.Factory opcional como parámetro.
class MyViewModelFactory( private val dbname: String ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(MyViewModel::class.java)) { return MyViewModel(dbname) as T } throw IllegalArgumentException("Unknown ViewModel class") } }Para crear su modelo de vista, pasará un parámetro opcional. Dentro de tu Composable puedes hacer algo como esto.
val viewModel: MyViewModel = viewModel( factory = MyViewModelFactory( dbname = "myDbName" )necesita crear una fábrica para pasar parámetros dinámicos a ViewModel de esta manera:
class MyViewModelFactory(private val dbname: String) : ViewModelProvider.NewInstanceFactory() { override fun <T : ViewModel?> create(modelClass: Class<T>): T = MyViewModel(dbname) as T }luego usa tu fábrica así en funciones componibles:
@Composable fun UsersList() { val myViewModel: MyViewModel = viewModel(factory = MyViewModelFactory("db2name")) // pass param like this }y ahora tiene acceso al parámetro dbname en su ViewModel:
class MyViewModel(private val dbname) : ViewModel() { // ...rest of the viewModel logics here }Por lo general, no hay un caso común en el que necesite hacer esto. En Android, los modelos de vista MVVM obtienen sus datos de los repositorios a través de la inyección de dependencia.
Aquí está la documentación oficial de la arquitectura de Android recomendada: https://developer.android.com/jetpack/guide#recommended-app-arch