簡體   English   中英

如何在可組合的 function 中正確創建 ViewModel object?

[英]How to create a ViewModel object inside composable function correctly?

我的 MainActivity 中有這個結構:

val navController = rememberNavController()
NavHost(
    navController = navController,
    startDestination = ItemsScreen.route
) {
    composable(
        route = ItemsScreen.route
    ) {
        ItemsScreen(
            navController = navController
        )
    }
    composable(
        route = ItemDetailsScreen.route + "/{itemId}",
        arguments = mutableStateListOf(
            navArgument("itemId") {
                type = NavType.StringType
            }
        )
    ) { backStackEntry ->
        val itemId = backStackEntry.arguments?.getString("itemId") ?: ""
        ItemDetailsScreen(
            navController = navController,
            itemId = itemId
        )
    }
}

在 ItemDetailsScreen 中的一個 LazyColumn:

LazyColumn {
    items(
        items = itemsResponse.data
    ) { item ->
        ItemCard(
            item = item,
            onItemClick = {
                navController.navigate(ItemDetailsScreen.route + "/${item.id}")
            }
        )
    }
}

在項目單擊時,我導航到 ItemDetailsScreen:

fun ItemDetailsScreen(
    navController: NavController,
    itemId: String,
    viewModel: ItemDetailsViewModel = hiltViewModel()
) {
    Log.d(TAG, itemId)
}

如圖所示,ViewModel object 是在構造函數中創建的。 當我打開 ItemDetailsScreen 時,會觸發兩次日志語句。 如果我評論這一行:

//viewModel: ItemDetailsViewModel = hiltViewModel()

日志語句按預期工作,它只打印一次 itemId。 如何使用 ViewModel object 使其只能觸發一次日志語句?

這也是 ViewModel class:

@HiltViewModel
class ItemDetailsViewModel @Inject constructor(
    private val useCases: UseCases
): ViewModel() {
    private val _itemState = mutableStateOf<Response<Item>>(Success(Item()))
    val itemState: State<Response<Item>> = _itemState

    fun getItem(id: String) {
        viewModelScope.launch {
            useCases.getItem(id).collect { response ->
                _itemState.value = response
            }
        }
    }
}

您不必擔心日志語句被打印兩次。 viewModel 創建代碼沒有任何問題。 日志語句被打印兩次,因為它直接位於可組合 function 內,並且可組合重組很多(有時甚至以不可預測的方式)。 如果您只想在第一次組合可組合項時執行某些操作,請將其放在LaunchedEffect塊中。 查看文檔以了解有關這些效果處理程序的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM