繁体   English   中英

如何在撰写导航中导航视图 model 字段更改?

[英]How to navigate on view model field change in Compose Navigation?

在我的应用程序中,我想将信息发送到服务器,并在收到成功响应后,我想将信息传递到当前屏幕以导航到另一个屏幕。

这是流程:

从 UI 我调用viewModel向服务器发送请求。 ViewModel我有一个回调:

@HiltViewModel
class CreateAccountViewModel @Inject constructor(
    private val cs: CS
) : ViewModel() {

    private val _screen = mutableStateOf("")

    val screen: State<String> = _screen

    fun setScreen(screen: Screen) {
        _screen.value = screen.route
    }

    private val signUpCallback = object : SignUpHandler {
        override fun onSuccess(user: User?, signUpResult: SignUpResult?) {
            setScreen(Screen.VerifyAccountScreen)
            Log.i(Constants.TAG, "sign up success")

        }

        override fun onFailure(exception: Exception?) {
            Log.i(Constants.TAG, "sign up failure ")
        }

    }
}

如您所见,我还有State负责屏幕,因此当响应成功时,我想更新 state 以便 UI 层(屏幕)知道它应该导航到另一个屏幕。 我的问题是:我如何观察 State

@Composable
fun CreateAccountScreen(
    navController: NavController,
    viewModel: CreateAccountViewModel = hiltViewModel()
) {
}

还是有更好的方法来实现这一目标?

我认为您的观点 model 应该对导航路线一无所知。 在这种情况下,简单的verificationNeeded标志就足够了:

var verificationNeeded by mutableStateOf(false)
    private set

private val signUpCallback = object : SignUpHandler {
    override fun onSuccess(user: User?, signUpResult: SignUpResult?) {
        verificationNeeded = true
        Log.i(Constants.TAG, "sign up success")
    }

    override fun onFailure(exception: Exception?) {
        Log.i(Constants.TAG, "sign up failure ")
    }
}

最佳实践是不在管理NavHost的视图之外共享navController ,并且只传递偶数处理程序。 当您需要测试或预览屏幕时,它可能很有用。

以下是更改此标志时的导航方式:

@Composable
fun CreateAccountScreen(
    onRequestVerification: () -> Unit,
    viewModel: CreateAccountViewModel = hiltViewModel(),
) {
    if (viewModel.verificationNeeded) {
        LaunchedEffect(Unit) {
            onRequestVerification()
        }
    }
}

在您的导航管理视图中:

val navController = rememberNavController()
NavHost(
    navController = navController,
    startDestination = Screen.CreateAccount
) {
    composable(Screen.CreateAccount) {
        CreateAccountScreen(
            onRequestVerification = {
                navController.navigate(Screen.VerifyAccountScreen)
            }
        )
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM