简体   繁体   English

如何从存储库返回 LiveData

[英]How to Return LiveData from Repository

I just can't see how to chain LiveData from Repo to VM, so I have tried to boil this down to the most simple of example!:我只是看不到如何将 LiveData 从 Repo 链接到 VM,因此我尝试将其归结为最简单的示例!:

Fragment分段

class LoginFragment : Fragment() {

private lateinit var loginViewModel: LoginViewModel
private var mCurrentName = "Blank!"

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val binding: LoginFragmentBinding = DataBindingUtil.inflate(
        inflater, R.layout.login_fragment, container, false)

    binding.apply {
        loginButton.setOnClickListener{
            loginViewModel.changeText()
        }
    }
    return binding.root
}


override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    loginViewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)

    loginViewModel.getCurrentName().observe(viewLifecycleOwner, Observer {
        mCurrentName = it      // I'm expecting mCurrentName to equal "Button Clicked!" when button clicked..
        makeToast()     // Toast works, but variable remains unchanged..
    })

}

private fun makeToast() {
    Toast.makeText(activity, mCurrentName, Toast.LENGTH_LONG).show()
}

ViewModel视图模型

class LoginViewModel : ViewModel() {

private val firestoreRepository : FirestoreRepository = FirestoreRepository()
private var mCurrentName = MutableLiveData<String>()

fun changeText(){
    mCurrentName = firestoreRepository.changeText()
}

Repository存储库

class FirestoreRepository {

    private val mCurrentName = MutableLiveData<String>()

    fun changeText(): MutableLiveData<String> {
            mCurrentName.value = "Button Clicked!!"
            return mCurrentName
    }

I'm assuming I have misunderstood how the observer function works..我假设我误解了观察者功能的工作原理..

Actually If you are maintaining LiveData in repository, I don't think there's a need of separate LiveData in ViewModel as well.实际上,如果您在存储库中维护LiveData ,我认为在ViewModel也不需要单独的LiveData You just have to observe the LiveData once from the activity.您只需要从活动中观察一次 LiveData。 Then make any changes to repository instance directly.然后直接对存储库实例进行任何更改。 So If I have to show it in your code, It might look something like this.所以如果我必须在你的代码中展示它,它可能看起来像这样。

  1. Activity class: Change makeToast method to observeCurrentName() like this:活动类:将 makeToast 方法更改为observeCurrentName(),如下所示:

     private fun observeCurrentName() { vm.getCurrentName().observe(this, Observer{ //Toast here }) }
  2. Your VM:你的虚拟机:

     class LoginViewModel : ViewModel() { ... fun getCurrentName(): MutableLiveData<String>{ return repository.getCurrentName() } fun setCurrentName(name: String?){ repository.setCurrentName(name) } ... }
  3. Your repository:您的存储库:

     class FirestoreRepository { private val mCurrentName = MutableLiveData<String>() fun getCurrentName(): MutableLiveData<String>{ return mCurrentName } fun setCurrentName(name: String?){ mCurrentName.value = name //This will trigger observer in Activity } }

No need to change MutableLiveData inside ViewModel .无需在ViewModel更改MutableLiveData Try to pass whatever Repository send to View .尝试将Repository发送的任何内容传递给View Check below检查下面

class LoginViewModel : ViewModel() {

    private val firestoreRepository : FirestoreRepository = FirestoreRepository()

    fun getCurrentName(): MutableLiveData<String> {
        return firestoreRepository.getCurrentName()
    }

    fun changeText() {
        firestoreRepository.changeText()
    }
}

And also your FirestoreRepository还有你的FirestoreRepository

class FirestoreRepository {

    private val mCurrentName = MutableLiveData<String>()

    fun getCurrentName(): MutableLiveData<String> {
        return mCurrentName
    }

    fun changeText() {
        mCurrentName.value = "Button Clicked!!"
    }
}

You're changing mCurrentName (the LiveData variable itself as opposed to it's contents) after you start observing it.在您开始观察它之后,您正在更改mCurrentName (LiveData 变量本身而不是它的内容)。 The guidance seems to be to not use LiveData in Repository layer (use Coroutines/Flow instead for example)....but for now you could have something like following (or perhaps use one of the LiveData Transformations)该指导似乎是不使用LiveData在库层(使用协同程序/流量,而不是例如)......但现在你可以有类似以下的(或者使用LiveData变革之一)

private val mCurrentName = firestoreRepository.currentName()

fun changeText(){
    firestoreRepository.changeText()
}

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

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