【发布时间】:2020-04-08 21:46:14
【问题描述】:
我正在使用 MVVM,并且我已经对其进行了不同的实现,但我仍然怀疑的一件事是如何在不将任何生命周期附加到 ViewModel 的情况下从我的 ViewModel 从存储库 (Firebase) 获取数据.
我已经从 ViewModel 实现了observeForever(),但我认为这不是一个好主意,因为我认为我应该使用回调或转换从我的存储库与我的 ViewModel 进行通信。
我在这里留下一个示例,我从 Firebase 获取设备并更新我的 UI,如果我们可以在这里看到,我正在观察来自 UI 的 repo 的数据,但我也在观察来自 ViewModel 的数据从回购,这里是我真的怀疑我是否使用了正确的方法,因为我不知道如果我的视图被破坏,observeForever() 是否会在onCleared() 上被清除,所以它不会保留如果视图死亡,观察者还活着。
用户界面
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
val deviceId = editText.text.toString().trim()
observeData(deviceId)
}
}
fun observeData(deviceId:String){
viewModel.fetchDeviceData(deviceId).observe(this, Observer {
textView.text = "Tipo: ${it.devType}"
})
视图模型
class MainViewmodel: ViewModel() {
private val repo = Repo()
fun fetchDeviceData(deviceId:String):LiveData<Device>{
val mutableData = MutableLiveData<Device>()
repo.getDeviceData(deviceId).observeForever {
mutableData.value = it
}
return mutableData
}
}
存储库
class Repo {
private val db = FirebaseDatabase.getInstance().reference
fun getDeviceData(deviceId:String):LiveData<Device>{
val mutableData = MutableLiveData<Device>()
db.child(deviceId).child("config/device").addListenerForSingleValueEvent(object: ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot) {
val device = dataSnapshot.getValue(Device::class.java)
mutableData.value = device
}
override fun onCancelled(dataError: DatabaseError) {
Log.e("Error","handle error callback")
}
})
return mutableData
}
}
这个例子只是展示了如何从 Firebase 获取设备,它可以工作,但是从我的 ViewModel 中,它一直让我觉得 observeForever() 不是我在寻找在存储库与 ViewModel 之间进行数据通信的东西。
我见过Transformations,但在这种情况下,我只需要将整个 Device 对象传递到我的 UI,因此我不需要将要检索的对象转换为另一个对象
这里应该有什么正确的方法来正确地传达存储库和 ViewModel?
【问题讨论】:
-
为什么需要Repository层? ViewModel + LiveData 不提供所有这些。您甚至可以将
viewModelScope.launch用于结构化并发。 -
我曾经有不同的模块来构建我的应用程序,因为存储库应该与数据层通信,为了不编写更多代码,我将这个示例缩小了一些,但我正在寻找的是如何在不从视图模型中永久观察的情况下与其他层交互
-
@IgorGanapolsky 这就是 MVVM 的想法
-
@MasterZzzingKhmer_Cambodia MVVM 不需要存储库层。
-
@IgorGanapolsky 是的,没有必要,但它可以保持代码干净。这是一个单一的责任原则。
标签: android kotlin mvvm android-livedata android-architecture-components