Android-модель модели сопрограммы - PullRequest
0 голосов
/ 05 февраля 2019

Хотелось бы услышать некоторых критиков о том, как я реализовал выборку данных модели представления с использованием сопрограммы.Моя цель - чистый способ написания ViewModels.Но не слишком ли много накладных расходов?Я пока не нашел чистого решения.Дайте мне знать ваши советы.Я хотел избежать написания if (!::users.isInitialized), как в официальном учебнике .

class LiveDataLoader <T>{
    val liveData = MutableLiveData<T>()
    var loaded:Boolean = false
}

abstract class CustomViewModel : ViewModel(){
    private val viewModelJob = Job()
    private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)

    fun <T> get(container: LiveDataLoader<T>, loader: ()->T): LiveData<T>{
        if (!container.loaded){
            container.loaded = true
            uiScope.launch{
                container.liveData.postValue(loader.invoke())
            }
        }
        return container.liveData;
    }

    override fun onCleared() {
        super.onCleared()
        viewModelJob.cancel()
    }
}

class ActivityTodoGroupsViewModel() : CustomViewModel(){
    private val groups = LiveDataLoader<MutableList<TaskGroupWithTasks>>()
    private val tasks = LiveDataLoader<MutableList<TodoTask>>()

    private lateinit var tasksx: MutableLiveData<MutableList<TodoTask>>

    fun getTaskGroups() = get(groups){
        AppDatabase.db.toDoTasksDAO.getGroupsWithItems()
    }

    fun getUpcomingTasks() = get(tasks){
        val calendar = Calendar.getInstance()
        calendar.add(Calendar.DAY_OF_YEAR, -7)
        AppDatabase.db.toDoTasksDAO.getRecentTasks(calendar)
    }

}

1 Ответ

0 голосов
/ 06 февраля 2019

В общем, всегда хорошо не показывать слишком много типов Mutable*.Это обеспечивает согласованность данных.Также кажется, что вы пытаетесь достичь чего-то похожего на lazy, так почему бы не использовать его.

Так что вы можете рассмотреть функцию расширения для CoroutineScope в конвертирования приостановкифункция для простого LiveData:

fun <V> CoroutineScope.liveData(
        provider: suspend () -> V
) = lazy<LiveData<V>> {
    MutableLiveData<V>().apply {
        launch {
            postValue(provider())
        }
    }
}

Если у вас также есть ViewModel орудие CoroutineScope, вы можете использовать его как:

val taskGroups() by liveData {
    AppDatabase.db.toDoTasksDAO.getGroupsWithItems()
}
...