首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在嵌套可组合中使用相同的hiltViewModel实例?

如何在嵌套可组合中使用相同的hiltViewModel实例?
EN

Stack Overflow用户
提问于 2022-08-03 05:31:58
回答 1查看 320关注 0票数 0

我有一个名为'Page‘的可组合函数,它是一个基本的可组合函数,可以为我的应用程序保存NavHost,请参见下面的体系结构:

代码语言:javascript
复制
@Composable
fun Page(viewModel: LdvToolViewModel = hiltViewModel(), scaffoldState: ScaffoldState, navController: NavHostController){
    val statusBarMode = viewModel.statusBarUiState
    val uiController = rememberSystemUiController()

    LaunchedEffect(statusBarMode){
        uiController.run {
            if(statusBarMode.isDarkContent){
                setStatusBarColor(color = Color.White, darkIcons = true)
            }else{
                setStatusBarColor(color = LdvOrange, darkIcons = false)
            }
        }
    }
    
    val navBuilder: NavGraphBuilder.() -> Unit = {
        composable(LdvPages.SEARCHING.name) { SearchUi(viewModel, scaffoldState = scaffoldState) }
        composable(LdvPages.ERROR.name) { ErrorUi(viewModel,scaffoldState = scaffoldState) }
        composable(LdvPages.PANEL.name) { PanelUi(scaffoldState,viewModel, mBaseViewModel) }
        composable(LdvPages.PrivacyPolicy.name){ PrivacyPolicy(scaffoldState)}
        composable(LdvPages.TermsOfUse.name){ TermsOfUse(scaffoldState)}
        composable(LdvPages.OpenSourceLicense.name){ OpenSourceLicense(scaffoldState)}
        composable(LdvPages.DebugPage.name){ DebugPage(viewModel)}
    }
    val start by derivedStateOf {
        if (...){
            LdvPages.PANEL.name }else if(...){
            LdvPages.ERROR.name
            }else{LdvPages.SEARCHING.name}
    }

    NavHost(navController = navController, startDestination = start, builder = navBuilder)
    if(!isNfcEnable){
        viewModel.setNfcDisableContent()
        ErrorDialog(viewModel = viewModel){
            startActivity(Intent(Settings.ACTION_NFC_SETTINGS));
        }
    }
    
}

如您所见,“LdvToolViewModel”已被注入到“Page”中作为hiltViewModel。为了将“LdvToolViewModel”作为navBuilder中嵌套可组合函数的生命周期中的一个实例,我必须将它作为参数传递给这些函数。有没有更好的方法,比如我可以在那些函数中注入“LdvToolViewModel”作为hiltViewModel,同时我仍然可以将注入的hiltViewModel作为一个相同的实例?

EN

回答 1

Stack Overflow用户

发布于 2022-09-13 00:02:38

假设您有一个"HomeGraph","Home“作为父目的地,很少有目标屏幕应该共享相同的ViewModel实例。

首先,通过传递父路由获得一个NavBackStackEntry

代码语言:javascript
复制
val parentEntry: NavBackStackEntry = remember(navBackStackEntry) {
                navController.getBackStackEntry(Destination.HomeGraph.route)
            }

然后通过传递父ViewModel来获取NavBackStackEntry的实例。

代码语言:javascript
复制
val userViewModel = hiltViewModel<HomeViewModel>(parentEntry)

另外,请记住,如果您从嵌套导航或从不同的图导航到Destination.HomeGraph.route,那么将创建一个新的ViewModel实例,因此如果您在单个图中导航,则导航到startDestination (例如Destination.Home.route )--这样您将保持相同的ViewModel实例。

我不认为我们在撰写过程中有一个定义良好的ViewModel共享,比如通过activityViewModels()实现视图系统的共享,但是在用户不访问ViewModel状态的情况下,将ViewModel状态保持在图形中是一种糟糕的做法。如果有必要,您可以在图形扩展函数中传递ViewModel。

代码语言:javascript
复制
fun NavGraphBuilder.homeGraph(navController: NavHostController) {
    navigation(
        startDestination = Destination.Home.route,
        route = Destination.HomeGraph.route
    ) {
        composable(Destination.Home.route) { navBackStackEntry ->
            val parentEntry = remember(navBackStackEntry) {
                navController.getBackStackEntry(Destination.HomeGraph.route)
            }
            val homeViewModel = hiltViewModel<HomeViewModel>(parentEntry)

            HomeRoute(
                viewModel = homeViewModel,
                onNavigate = { dest ->
                navController.navigate(dest.route)
            })
        }

        composable(Destination.Search.route) { navBackStackEntry ->
            val parentEntry = remember(navBackStackEntry) {
                navController.getBackStackEntry(Destination.HomeGraph.route)
            }
            val homeViewModel = hiltViewModel<HomeViewModel>(parentEntry)
            UserSupportRoute(
                viewModel = userViewModel,
                onNavigate = { dest ->
                navController.navigate(dest.route) {
                    popUpTo(Destination.Search.route) {
                        inclusive = true
                    }
                }
            })
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73216665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档