如何再次调用 LiveData 协程块

Jan*_*C12 8 android kotlin android-livedata android-viewmodel kotlin-coroutines

我正在使用 LiveData 的版本“androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha05”。一旦我的 LiveData 块成功执行,我想明确触发它再次执行,例如

  1. 我导航到一个片段
  2. 用户数据加载
  3. 我在同一个片段中单击删除 btn
  4. 用户的数据应该刷新

我有一个片段,用于观察我的 LiveData,一个带有 LiveData 和 Repository 的 ViewModel:

视图模型:

  fun getUserLiveData() = liveData(Dispatchers.IO) {

   val userData = usersRepo.getUser(userId)

   emit(userData) 
}
Run Code Online (Sandbox Code Playgroud)

分段:

viewModel.getUserLiveData.observe(viewLifecycleOwner,
            androidx.lifecycle.Observer {.. 
Run Code Online (Sandbox Code Playgroud)

然后我试图实现这样的期望行为:

viewModel.deleteUser()

viewModel.getUserLiveData()
Run Code Online (Sandbox Code Playgroud)

根据下面的文档,如果 LiveData 块已成功完成,并且如果我在 LiveData 块中放了一个while(true),则不会执行以下文档,然后我的数据会刷新,但是我不希望这样做,因为我需要更新我的反应性地看待。

如果[block]成功完成由于[LiveData]变为非活动以外的原因被取消,即使[LiveData]经过活动非活动周期后也不会重新执行。

也许我错过了如何重用相同的 LiveDataScope 来实现这一目标?任何帮助,将不胜感激。

小智 2

要使用 liveData { .. } 块执行此操作,您需要定义一些命令源,然后在块中订阅它们。例子:

MyViewModel() : ViewModel() {
   val commandsChannel = Channel<Command>()

   val liveData = livedata {
      commandsChannel.consumeEach { command -> 
            // you could have different kind of commands 
             //or emit just Unit to notify, that refresh is needed
           val newData = getSomeNewData()
           emit(newData)
       }
   }

  fun deleteUser() {
   .... // delete user
   commandsChannel.send(RefreshUsersListCommand)
  }
}
Run Code Online (Sandbox Code Playgroud)

你应该问自己的问题:也许使用普通的 MutableLiveData 来代替,并自己改变它的值会更容易?

当您可以收集一些数据流(例如来自 Room DB 的 Flow / Flowable)时,livedata { ... } 构建器效果很好,但对于普通的非流源则效果不佳,您需要自己请求数据。