我正在开发一个 Kotlin 多平台 (KMP) 项目,我遇到一个问题:当我从 Compose 屏幕触发 ViewModel 中的方法时,该方法不会被调用。我的 ViewModel 位于 commonMain 模块中,并实现 KoinComponent 进行依赖注入。但是,当我尝试从 Compose 屏幕中的 ViewModel 调用方法时,它不会被执行,并且不会出现该方法的日志。
commonMain 中的代码(RegistrationViewModel)
class RegistrationViewModel : CoroutineViewModel(), KoinComponent {
fun signUp(request: SignUpRequest) {
println("signUp method called with request: $request")
}
}
androidMain(注册屏幕)中的代码:
@Composable
fun RegistrationScreen(
onSignInClicked: () -> Unit,
onRegisterButtonClicked: () -> Unit,
navigateToMainScreen: () -> Unit
) {
val viewModel = remember { RegistrationViewModel() }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
val loginValue = remember { mutableStateOf("") }
val emailValue = remember { mutableStateOf("") }
val passwordValue = remember { mutableStateOf("") }
FPButton(text = "Sign In", onClick = {
val signUpRequest = SignUpRequest(
name = loginValue.value,
emailAddress = emailValue.value,
password = passwordValue.value
)
println("Button clicked, calling signUp()")
viewModel.signUp(signUpRequest)
})
}
}
问题: 当我单击“登录”按钮时,我看到日志“单击按钮,调用signUp()”,但来自signUp()方法的日志(“使用请求调用的signUp方法:$request”)从未出现。这表明该方法没有被执行。
我尝试过的: 将记住 { RegistrationViewModel() } 替换为 koinViewModel():
val viewModel: RegistrationViewModel = koinViewModel()
这并没有解决问题。
问题:
为什么 ViewModel 没有调用方法signUp()?
这可能与 KMP 项目中 commonMain 中创建 ViewModel 的方式有关吗?
在带有 Koin 的 KMP 上下文中使用 Remember { RegistrationViewModel() } 是否有问题?
import org.koin.dsl.module
import org.koin.androidx.viewmodel.dsl.viewModel
val appModule = module {
viewModel { RegistrationViewModel() }
}
import org.koin.androidx.compose.getViewModel
@Composable
fun RegistrationScreen(
onSignInClicked: () -> Unit,
onRegisterButtonClicked: () -> Unit,
navigateToMainScreen: () -> Unit
) {
// Use Koin’s getViewModel() to inject RegistrationViewModel
val viewModel: RegistrationViewModel = getViewModel()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
val loginValue = remember { mutableStateOf("") }
val emailValue = remember { mutableStateOf("") }
val passwordValue = remember { mutableStateOf("") }
FPButton(text = "Sign In", onClick = {
val signUpRequest = SignUpRequest(
name = loginValue.value,
emailAddress = emailValue.value,
password = passwordValue.value
)
println("Button clicked, calling signUp()")
viewModel.signUp(signUpRequest) // This should now be called properly
})
}
}
解释 Koin 的 getViewModel():此函数确保 RegistrationViewModel 正确注入 Koin 并在 Compose 中使用正确的生命周期进行管理。 避免
remember { RegistrationViewModel() }
:直接将remember与RegistrationViewModel一起使用会绕过Koin并且不提供生命周期感知,这在需要通过依赖注入来管理共享组件的KMP项目中尤其重要。
在 Kotlin Multiplatform 中,您可以按如下方式实例化 ViewModel:
val viewModel = viewModel { RegistrationViewModel() }
来源:Common ViewModelufeff