在视图模型 MutableStateFlow mvi 中检查响应请求

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

我目前正在开发一个利用 MVI(模型-视图-意图)架构的 Android 应用程序。在我的 ViewModel 中,我使用 MutableStateFlow 来管理 UI 状态。我想优化我的代码,以防止在检查 ViewModel 状态中的响应请求时进行重复工作。

我已经实现了以下方法来处理 ViewModel 中的响应请求:

@HiltViewModel
class ListViewModel @Inject constructor(private val repository: ListRepository) : ViewModel() {
    val intentChannel = Channel<ListIntent>()
    private val _state = MutableStateFlow<ListState>(ListState.Idle)
    val state: StateFlow<ListState> get() = _state

    init {
        handleIntents()
    }

    private fun handleIntents() = viewModelScope.launch {
        intentChannel.consumeAsFlow().collect { intent ->
            when (intent) {
                is ListIntent.LoadFiltersLetters -> fetchingFiltersList()
                is ListIntent.LoadRandom -> fetchingRandomFood()
                is ListIntent.LoadCategoriesList -> fetchingCategoriesList()
                is ListIntent.LoadFoods -> fetchingFoodsList(intent.letter)
                is ListIntent.LoadSearchFoods -> fetchingSearchFood(intent.search)
                is ListIntent.LoadFoodByCategory -> fetchingFoodsByCategory(intent.category)
            }
        }
    }

    private fun fetchingFoodsByCategory(category: String) = viewModelScope.launch {
        val response = repository.foodByCategory(category)
        _state.emit(ListState.LoadingFoods)
        when (response.code()) {
            in 200..202 -> {
                _state.value = if (response.body()!!.meals != null) {
                    ListState.FoodsList(response.body()!!.meals!!)
                } else {
                    ListState.Empty
                }
            }
            in 400..499 -> {
                _state.emit(ListState.Error(""))
            }
            in 500..599 -> {
                _state.emit(ListState.Error(""))
            }
        }
    }

    private fun fetchingSearchFood(search: String) = viewModelScope.launch {
        val response = repository.searchFood(search)
        _state.emit(ListState.LoadingFoods)
        when (response.code()) {
            in 200..202 -> {
                _state.value = if (response.body()!!.meals != null) {
                    ListState.FoodsList(response.body()!!.meals!!)
                } else {
                    ListState.Empty
                }
            }
            in 400..499 -> {
                _state.emit(ListState.Error(""))
            }
            in 500..599 -> {
                _state.emit(ListState.Error(""))
            }
        }
    }

    private fun fetchingFoodsList(letter: String) = viewModelScope.launch {
        val response = repository.foodsList(letter)
        _state.emit(ListState.LoadingFoods)
        when (response.code()) {
            in 200..202 -> {
                _state.value = if (response.body()!!.meals != null) {
                    ListState.FoodsList(response.body()!!.meals!!)
                } else {
                    ListState.Empty
                }
            }
            in 400..499 -> {
                _state.emit(ListState.Error(""))
            }
            in 500..599 -> {
                _state.emit(ListState.Error(""))
            }
        }
    }

    private fun fetchingCategoriesList() = viewModelScope.launch {
        val response = repository.categoriesList()
        _state.emit(ListState.LoadingCategory)
        when (response.code()) {
            in 200..202 -> {
                _state.emit(ListState.CategoriesList(response.body()!!.categories))
            }
            in 400..499 -> {
                _state.emit(ListState.Error(""))
            }
            in 500..599 -> {
                _state.emit(ListState.Error(""))
            }
        }
    }

    private suspend fun fetchingRandomFood() {
        val response = repository.randomFood()
        when (response.code()) {
            in 200..202 -> {
                _state.emit(ListState.RandomFood(response.body()?.meals?.get(0)))
            }
            in 400..499 -> {
                _state.emit(ListState.Error(""))
            }
            in 500..599 -> {
                _state.emit(ListState.Error(""))
            }
        }
    }

    private suspend fun fetchingFiltersList() {
        val list = listOf('A'..'Z').flatten().toMutableList()
        _state.emit(ListState.FilterLetters(list))
    }
}
 when (response.code()) {
            in 200..202 -> {
            }
            in 400..499 -> {
            }
            in 500..599 -> {
            }
}

但是,我发现自己为不同的功能重复类似的代码,这不是最佳的 我听说使用协程和流可以帮助避免这种重复。您能否指导我如何使用协程和流程改进此代码,以最大限度地减少冗余,同时有效处理响应请求?您的见解和代码示例将不胜感激。谢谢!

我使用mvi架构

 when (response.code()) {
            in 200..202 -> {
            }
            in 400..499 -> {
            }
            in 500..599 -> {
            }
}

我想在 ViewModel 中执行此操作,而不是在存储库中,并避免重复代码

kotlin retrofit2 kotlin-coroutines kotlin-stateflow
1个回答
0
投票

将所有这些代码传输到存储库,只需更改视图模型中的状态流值并在片段/活动中观察它。 创建一个具有 int 值的枚举类来表示这些方法。只需将枚举类型和查询字符串发送到存储库即可。根据这些枚举类型进行切换,并调用食物的数据库方法并相应地返回列表。希望你理解。

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