观察变量和函数有什么区别

时间:2020-07-22 20:36:09

标签: android kotlin mvvm viewmodel android-architecture-components

当我从片段A观察到我的视图模型中的一个变量时

val fetchTopicsList = liveData(Dispatchers.IO) {
        emit(Resource.Loading())
        try {
            emit(repo.getIdeas())
        }catch (e:Exception){
            emit(Resource.Failure(e))
        }
    }

然后我导航到片段B,然后回到片段A,观察者将再次触发,但是不会获取新数据。

现在,如果我将该声明更改为函数声明

fun fetchTopicsList() = liveData(Dispatchers.IO) {
        emit(Resource.Loading())
        try {
            emit(repo.getIdeas())
        }catch (e:Exception){
            emit(Resource.Failure(e))
        }
    }

当我执行相同操作(从片段A转到片段B并返回)时,观察者将再次触发并再次从服务器提取数据。

为什么在变量仅保留第一个获取的数据时函数再次触发?

1 个答案:

答案 0 :(得分:1)

您实际上可能想要一个MutableLiveData的实例,该实例会在某些交互作用下发出,但是我想直接解决您的问题:

使用该函数,每次调用都会为您提供LiveData的新实例,而使用属性初始化器将实例化+在实例化您的类时将其设置为LiveData的单个实例。这意味着,如果您的媒体资源位于ViewModel上,它将通过更改配置并暂停/恢复循环直到被销毁而继续存在。

如果您喜欢属性语法,则可以通过重写getter使其与每次重新调用该函数的功能相同,但是说实话,此处的函数在语法上更准确。

这是通过属性语法实现相同功能的方式:

val fetchTopicsList: LiveData<..>
  get() = liveData(Dispatchers.IO) {
     emit(Resource.Loading())
     try {
       emit(repo.getIdeas())
     } catch (e:Exception){
       emit(Resource.Failure(e))
     }
  }

同样,更好的方法可能是使用单个MutableLiveData并在ViewModel上公开一个函数以发出请求并为任何订阅者发布值。