如何从 jetpack compose 将参数传递到我的柄视图模型

问题描述 投票:0回答:3

我有一个带有视图模型的可组合项,我想将一个 id 从可组合项传递到视图模型。

我的可组合项是:

@Composable
fun HttpRequestScreen(
    viewModel: HttpRequestViewModel = hiltViewModel(),
    id: String = EMPTYUUID,
    onClick: (String, String, Int) -> Unit // respond, request Function: 1 - send request, 2 - edit request
) {

我有来自不同屏幕的 ID,我想将其传递到我的 Hilt 视图模型。

android mvvm android-jetpack-compose viewmodel dagger-hilt
3个回答
0
投票

假设您已遵循撰写导航的文档,您可以在此处找到您的参数:

@HiltViewModel
class RouteDetailsViewModel @Inject constructor(
    private val getRouteByIdUC: GetRouteByIdUC,
    private val savedStateHandle: SavedStateHandle
): ViewModel() {

    private val routeId = savedStateHandle.get<String>("your-param-name") // for example String in my case
}

0
投票

您需要以单向数据流模式进行思考,其中事件向上流动,状态向下流动。为此,您需要从视图模型中公开某种状态,将请求的状态作为可观察状态发送到可组合项。

你的视图模型可能看起来像这样。

class HttpRequestViewModel: ViewModel() {

    private val _httpResponse = mutableStateOf("")

    val httpResponse: State<String> = _httpResponse

    fun onHttpRequest(requestUrl: String) {
        // Execute your logic
        val result = "result of your execution"
        _httpResponse.value = result
    }
}

然后在您的 Composable 中,您可以通过在按钮单击上调用 ViewModel 函数来发送事件,如下所示

@Composable
fun HttpRequestScreen(viewModel: HttpRequestViewModel) {

    val state by viewModel.httpResponse

    var userInput = remember { TextFieldValue("") }

    Column {
        Text(text = "HTTP Response = $state")
    }

    BasicTextField(value = userInput, onValueChange = {
        userInput = it
    })

    Button(onClick = { viewModel.onHttpRequest(userInput.text) }) {
        Text(text = "Make Request")
    }
}

我希望这能为您指明正确的方向。祝你好运。


0
投票

如果您使用 Dagger Hilt,则通过 AndroidX 工件

key
 添加对 
androidx.hilt:hilt-navigation-compose
的支持。

或者,您可以自己创建这个内联函数:

import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.HiltViewModelFactory
import androidx.lifecycle.HasDefaultViewModelProviderFactory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel

/**
 * Returns an existing
 * [HiltViewModel](https://dagger.dev/api/latest/dagger/hilt/android/lifecycle/HiltViewModel)
 * -annotated [ViewModel] or creates a new one scoped to the current navigation graph present on
 * the {@link NavController} back stack.
 *
 * If no navigation graph is currently present then the current scope will be used, usually, a
 * fragment or an activity.
 *
 * @sample androidx.hilt.navigation.compose.samples.NavComposable
 * @sample androidx.hilt.navigation.compose.samples.NestedNavComposable
 */
@Composable
inline fun <reified VM : ViewModel> hiltViewModel(
    viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
        "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
    },
    key: String? = null
): VM {
    val factory = createHiltViewModelFactory(viewModelStoreOwner)
    return viewModel(viewModelStoreOwner, key, factory = factory)
}

@Composable
@PublishedApi
internal fun createHiltViewModelFactory(
    viewModelStoreOwner: ViewModelStoreOwner
): ViewModelProvider.Factory? = if (viewModelStoreOwner is HasDefaultViewModelProviderFactory) {
    HiltViewModelFactory(
        context = LocalContext.current,
        delegateFactory = viewModelStoreOwner.defaultViewModelProviderFactory
    )
} else {
    // Use the default factory provided by the ViewModelStoreOwner
    // and assume it is an @AndroidEntryPoint annotated fragment or activity
    null
}
© www.soinside.com 2019 - 2024. All rights reserved.