繁体   English   中英

在没有 LiveData 的情况下将数据从 Repository 返回到 ViewModel

[英]Return data from Repository to ViewModel without LiveData

我只是想找到一个答案,如何将数据从Repository传递到ViewModel而无需像RxJava这样的额外依赖项。 LiveData在这里似乎不是一个好的解决方案,因为我不需要在我的Presentation中继续它,只需要在ViewModel中进行,并且使用observeForever不是一个好习惯。 代码很简单:我使用 Firebase 示例尝试使用Flow传递数据但不能在侦听器中使用它(暂停函数只能在协程主体错误中调用):

资料库

    fun fetchFirebaseFlow(): Flow<List<MyData>?> = flow {
        var ret: List<MyData>? = null
        firebaseDb.child("data").addListenerForSingleValueEvent(
            object : ValueEventListener {
                override fun onDataChange(dataSnapshot: DataSnapshot) {
                    val data = dataSnapshot.getValue<List<MyData>>()
                    emit(data) // Error. How to return the data here?
                }

                override fun onCancelled(databaseError: DatabaseError) {
                    emit(databaseError) // Error. How to return the data here?
                }
            })
//        emit(ret) // Useless here
    }

视图模型

    private suspend fun fetchFirebase() {
        repo.fetchFirebaseFlow().collect { data ->
            if (!data.isNullOrEmpty()) {
                // Add data to something
            } else {
                // Something else
            }
    }

您可以使用回调流

@ExperimentalCoroutinesApi
    fun fetchFirebaseFlow(): Flow<List<String>?> = callbackFlow {
        
        val listener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                val data = dataSnapshot.getValue<List<MyData>>()
                offer(data)
            }

            override fun onCancelled(databaseError: DatabaseError) {
                
            }
        }
        val ref =firebaseDb.child("data")
        reef.addListenerForSingleValueEvent(listener)

        awaitClose{
            //remove listener here
           ref.removeEventListener(listener)
        }
    }

ObservableField类似于LiveData但不是生命周期感知的,可以用来代替创建Observable object。

{
    val data = repo.getObservable()

    val cb = object : Observable.OnPropertyChangedCallback() {
        override fun onPropertyChanged(observable: Observable, i: Int) {
            observable.removeOnPropertyChangedCallback(this)
            val neededData = (observable as ObservableField<*>).get()
        }
    }

    data.addOnPropertyChangedCallback(cb)
}


fun getObservable(): ObservableField<List<MyData>> {
    val ret = ObservableField<List<MyData>>()
    firebaseDb.child("events").addListenerForSingleValueEvent(
        object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                ret.set(dataSnapshot.getValue<List<MyData>>())
            }

            override fun onCancelled(databaseError: DatabaseError) {
                ret.set(null)
            }
        })
    return ret
}

也可以对单个结果使用suspendCancellableCoroutine 感谢Kotlin论坛

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM