Observation de LiveData à partir de Viewmodèle

j'ai une classe séparée dans laquelle je gère la collecte de données (en particulier Firebase) et je renvoie habituellement des objets LiveData de celle-ci et de les mettre à jour de façon asynchrone. Maintenant, je veux que les données retournées soient stockées dans un ViewModel, mais le problème est que pour obtenir cette valeur, je dois observer L'objet LiveData retourné de ma classe fetching de données. La méthode observe nécessitait un objet LifecycleOwner comme premier paramètre, mais je n'ai évidemment pas cela à l'intérieur de mon Modèlevue et je sais Je ne suis pas censé garder une référence à L'activité / Fragment à l'intérieur du modèle de vue. Que dois-je faire?

17
demandé sur Vuk Bibic 2017-11-27 19:51:05

2 réponses

ViewModel documentation

cependant, les objets ViewModel ne doivent jamais observer les changements des observables sensibles au cycle de vie, tels que les objets LiveData.

une autre façon pour les données est d'implémenter RxJava plutôt que LiveData, alors il n'aura pas l'avantage d'être conscient du cycle de vie.

dans un exemple de todo-mvvm-live-kotlin, il utilise un callback sans LiveData dans ViewModel.

je suis devinez si vous voulez vous conformer à l'idée d'être des objets du cycle de vie, nous devons déplacer le code d'observation dans activité/Fragment. Sinon, nous pouvons utiliser callback ou RxJava dans ViewModel.

un autre compromis est implémenter MediatorLiveData (ou Transformations) et observer (mettez votre logique ici) dans ViewModel. Remarque MediatorLiveData observer ne déclenchera pas (même que des Transformations) à moins qu'il ne soit observé dans L'activité/Fragment. Ce que nous faisons est de mettre une observation vierge dans L'activité/Fragment, où le vrai travail se fait en effet dans ViewModel.

// ViewModel
fun start(id : Long) : LiveData<User>? {
    val liveData = MediatorLiveData<User>()
    liveData.addSource(dataSource.getById(id), Observer {
        if (it != null) {
            // put your logic here
        }
    })
}

// Activity/Fragment
viewModel.start(id)?.observe(this, Observer {
    // blank observe here
})

PS: j'ai lu Viewmodel et LiveData: Modèles + AntiPatterns ce qui suggère que les Transformations. Je ne pense pas que cela fonctionne à moins que le LiveData soit observé (ce qui nécessite probablement qu'il soit fait à L'activité/Fragment).

4
répondu Desmond Lua 2018-06-27 18:17:10