emit
accepte la classe data
tandis que emitSource
accepte LiveData<T>
(T -> data
). Considérant l'exemple suivant: - J'ai deux types d'appels: -
suspend fun getData(): Data // returns directly data
et l'autre ;
suspend fun getData(): LiveData<Data> // returns live data instead
Pour le premier cas, je peux utiliser: -
liveData {
emit(LOADING)
emit(getData())
}
Ma question: L'utilisation de la méthode ci-dessus résoudrait mon problème, POURQUOI avons-nous besoin de emitSource(liveData)
de toute façon?
Tout bon cas d'utilisation pour utiliser la méthode
emitSource
le rendrait clair!
J'ai trouvé un vrai cas d'utilisation qui décrit l'utilisation de emitSource
sur emit
que j'ai utilisé plusieurs fois en production maintenant. : D Le cas d'utilisation:
Supposons que u ait des données utilisateur (User
qui ont des champs comme userId
, userName
) retournées par certains ApiService
.
Le modèle User
:
data class User(var userId: String, var userName: String)
userName
est requis par la vue/activité pour peindre l'interface utilisateur. Et le userId
est utilisé pour faire n autre appel API qui renvoie le UserData
comme profileImage
, emailId
.
Le modèle UserData
:
data class UserData(var profileImage: String, var emailId: String)
Ceci peut être réalisé en interne en utilisant emitSource
en câblant les deux liveData dans le ViewModel
comme:
User
liveData -
val userLiveData: LiveData<User> = liveData {
emit(service.getUser())
}
UserData
liveData -
val userDataLiveData: LiveData<UserData> = liveData {
emitSource(userLiveData.switchMap {
liveData {
emit(service.getUserData(it.userId))
}
})
}
Ainsi, dans l'activité/la vue, on peut SEULEMENT appeler getUser()
et la getUserData(userId)
sera déclenché automatiquement en interne via switchMap
.
Vous n'avez pas besoin manuellement d'appeler la getUserData(id)
en passant l'id.
Ceci est un exemple simple, imaginez qu'il existe une chaîne de tâches dépendantes qui doit être exécutée l'une après l'autre, chacune étant observée dans l'activité.
emitSource
entrehandy
Avec emitSource () , vous pouvez non seulement émettre une seule valeur, mais attacher votre LiveData à un autre LiveData et commencer à émettre à partir de celle-ci. Quoi qu'il en soit, chaque appel emit () ou emitSource () supprimera la source précédemment ajoutée.
var someData = liveData {
val cachedData = dataRepository.getCachedData()
emit(cachedData)
val actualData = dataRepository.getData()
emitSource(actualData)
}
L'activité qui observe l'objet someData recevra rapidement les données mises en cache sur l'appareil et mettra à jour l'interface utilisateur. Ensuite, le LiveData lui-même se chargera de faire la demande du réseau et de remplacer les données mises en cache par un nouveau flux de données en direct, qui déclenchera éventuellement l'observateur d'activité et mettra à jour l'interface utilisateur avec les informations mises à jour.