如何更新ViewModel中的StateFlow

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

我的可组合项中有此员工列表:

val employeeViewModel: EmployeeViewModel = viewModel()
val employeeState by employeeViewModel.employeeState.collectAsState(ViewResult.Loading)

ALlEmployees(employeeState = employeeState,
      onRefresh = {
         // TODO: Re-fetch the list
      })

这是我的视图模型

var employeeState: StateFlow<ViewResult<List<Employee>>> = fetchEmployeesUseCase().stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5_000),
            initialValue = ViewResult.Loading,
        )
private set

我真的不知道如何重新获取员工列表。该流程需要以某种方式重新触发。如有任何帮助,我们将不胜感激。

android android-viewmodel kotlin-flow android-compose
1个回答
0
投票

为了实现这一目标,我们首先要重构 viewModel。 我一贯的处理方式是这样的:

class EmployeeViewModel(
    private val repository: TestRepository
) : ViewModel() {

    // Here we store the value of the employee list status
    // We have the internal mutable state '_uiEmployeeState' and the public state 'uiEmployeeState'
    // The public state will be used in the composable to obtain the state value safely
    private val uiEmployeeState = MutableStateFlow<ViewResult<List<Employee>>>(ViewResult.Loading)
    val _uiEmployeeState: StateFlow<ViewResult<List<Employee>>> = uiEmployeeState

    // Use this function if you want the state to be updated every time the viewmodel is instantiated.
    init {
        fetchEmployees()
    }

    /**
     * Function that is responsible for updating the employee state
     *  - Use a 'viewModelScope' if the function is suspend, otherwise do it directly
     *  - Use 'update' to update the state value, you can also use '.value'
     *  - Use 'first' to get the first value of the flow and update the state
     */
    fun fetchEmployees() {
        uiEmployeeState.value = ViewResult.Loading
        viewModelScope.launch {
            uiEmployeeState.update {
                repository.fetchEmployeesUseCase().first()
            }
        }
    }

}

在viewModel内部的

fetchEmployees()
中,您可以将状态临时设置为
loading
,以防万一您有一些动画或类似的东西,否则您可以忽略它并直接更新状态。 另外,在我的示例中,我们从存储库获取数据,您可以将其更改为您的用例

在用户界面方面,它会是这样的:

val employeeViewModel: EmployeeViewModel = viewModel()
// You do not need to give it the initial value since the viewModel already has one
val employeeState by employeeViewModel._uiEmployeeState.collectAsState()

AllEmployees(
    employeeState = employeeState,
    onRefresh = { employeeViewModel.fetchEmployees() }
     // You can also use it as a lambda reference
    //onRefresh = employeeViewModel::fetchEmployees

)

另外,当您从 viewModel 听到状态时,您可以检查推荐的库:

->

collectAsStateWithLifecycle()

它仅以生命周期感知的方式从 Flow 或 StateFLow 收集值,从而允许您的应用程序节省不需要的应用程序资源。特别适用于您使用 StateFlow 的情况

我给你一个参考链接: https://developer.android.com/jetpack/compose/state?hl=es-419#use-other-types-of-state-in-jetpack-compose

© www.soinside.com 2019 - 2024. All rights reserved.