如何 Return 来自存储库的 LiveData
How to Return LiveData from Repository
我只是看不出如何将 LiveData 从 Repo 链接到 VM,所以我试图将其归结为最简单的示例!:
片段
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()
}
存储库
class FirestoreRepository {
private val mCurrentName = MutableLiveData<String>()
fun changeText(): MutableLiveData<String> {
mCurrentName.value = "Button Clicked!!"
return mCurrentName
}
我假设我误解了观察者函数的工作原理。
开始观察后,您正在更改 mCurrentName
(LiveData 变量本身而不是它的内容)。指导似乎是不要在存储库层中使用 LiveData
(例如,使用 Coroutines/Flow)......但是现在你可以有类似的东西(或者可能使用 LiveData 转换之一)
private val mCurrentName = firestoreRepository.currentName()
fun changeText(){
firestoreRepository.changeText()
}
无需更改 ViewModel
内的 MutableLiveData
。尝试将 Repository
发送给 View
的任何内容传递给 View
。检查下面
class LoginViewModel : ViewModel() {
private val firestoreRepository : FirestoreRepository = FirestoreRepository()
fun getCurrentName(): MutableLiveData<String> {
return firestoreRepository.getCurrentName()
}
fun changeText() {
firestoreRepository.changeText()
}
}
还有你的FirestoreRepository
class FirestoreRepository {
private val mCurrentName = MutableLiveData<String>()
fun getCurrentName(): MutableLiveData<String> {
return mCurrentName
}
fun changeText() {
mCurrentName.value = "Button Clicked!!"
}
}
实际上,如果您在存储库中维护 LiveData
,我认为 ViewModel
中也不需要单独的 LiveData
。您只需要从 activity 观察一次 LiveData。然后直接对存储库实例进行任何更改。所以如果我必须在你的代码中显示它,它可能看起来像这样。
Activity class:将 makeToast 方法更改为 observeCurrentName(),如下所示:
private fun observeCurrentName() {
vm.getCurrentName().observe(this, Observer{
//Toast here
})
}
您的虚拟机:
class LoginViewModel : ViewModel() {
...
fun getCurrentName(): MutableLiveData<String>{
return repository.getCurrentName()
}
fun setCurrentName(name: String?){
repository.setCurrentName(name)
}
...
}
您的存储库:
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
}
}
我只是看不出如何将 LiveData 从 Repo 链接到 VM,所以我试图将其归结为最简单的示例!:
片段
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()
}
存储库
class FirestoreRepository {
private val mCurrentName = MutableLiveData<String>()
fun changeText(): MutableLiveData<String> {
mCurrentName.value = "Button Clicked!!"
return mCurrentName
}
我假设我误解了观察者函数的工作原理。
开始观察后,您正在更改 mCurrentName
(LiveData 变量本身而不是它的内容)。指导似乎是不要在存储库层中使用 LiveData
(例如,使用 Coroutines/Flow)......但是现在你可以有类似的东西(或者可能使用 LiveData 转换之一)
private val mCurrentName = firestoreRepository.currentName()
fun changeText(){
firestoreRepository.changeText()
}
无需更改 ViewModel
内的 MutableLiveData
。尝试将 Repository
发送给 View
的任何内容传递给 View
。检查下面
class LoginViewModel : ViewModel() {
private val firestoreRepository : FirestoreRepository = FirestoreRepository()
fun getCurrentName(): MutableLiveData<String> {
return firestoreRepository.getCurrentName()
}
fun changeText() {
firestoreRepository.changeText()
}
}
还有你的FirestoreRepository
class FirestoreRepository {
private val mCurrentName = MutableLiveData<String>()
fun getCurrentName(): MutableLiveData<String> {
return mCurrentName
}
fun changeText() {
mCurrentName.value = "Button Clicked!!"
}
}
实际上,如果您在存储库中维护 LiveData
,我认为 ViewModel
中也不需要单独的 LiveData
。您只需要从 activity 观察一次 LiveData。然后直接对存储库实例进行任何更改。所以如果我必须在你的代码中显示它,它可能看起来像这样。
Activity class:将 makeToast 方法更改为 observeCurrentName(),如下所示:
private fun observeCurrentName() { vm.getCurrentName().observe(this, Observer{ //Toast here }) }
您的虚拟机:
class LoginViewModel : ViewModel() { ... fun getCurrentName(): MutableLiveData<String>{ return repository.getCurrentName() } fun setCurrentName(name: String?){ repository.setCurrentName(name) } ... }
您的存储库:
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 } }