首页 > 解决方案 > transformations.switchMap 只工作一次或可能根本不工作

问题描述

我正在寻找有关 transformations.switchMap 的帮助。我不知何故无法让它工作,并开始怀疑我是否真的理解正确。

根据我的理解,第一个参数就像一个触发器,每当它的值发生变化时,第二个参数/函数将被映射/调用以返回一个新的/修改的 liveData 对象。就我而言,我有:

#MainActivity
viewModel.repository.items.observe(requireActivity(), Observer { weight -> weight?.let { adapter!!.setItems(it) } })

#ViewModel
lateinit var items: LiveData<List<Weight>>      # Used in my RecyclerView
var filterChanged = MutableLiveData<Long>(0L)   # The "trigger" value

override fun init() {
    super.init()
    items = Transformations.switchMap(filterChanged) {repository.getItems(0L, filterEnd)}
}

repository.getItems() 返回由 filterEnd 过滤的实时数据对象(SQL ...其中时间戳 <= filterEnd),时间戳是数字表示的日期。

这行得通!但只有一次,在片段初始化期间。片段初始化后,我可以根据需要随时更改 filterChanged 触发器变量,不会再次调用 repository.getItems() 函数(为 filterEnd 应用更新的值)。

它需要启动/停止辅助活动(设置或关于),这将重新创建我的 viewModel 以更新过滤器值。

我看到了几种制作 Transformations.switchMap 语句的方法,使用 lambdas、一个或两个参数等,但我要么无法编译它们,要么它们没有达到我的预期。

现在,我是否正确理解了这应该如何工作?知道我可能做错了什么吗?

编辑:添加了存储库部分以澄清事情:

    #Repository
    items = getItems(filterStart, filterEnd) # This is where I enter from the ViewModel

    // This function redirects to the actual dao functions, 
    fun getItems(filterStart: Long, filterEnd: Long): LiveData<List<Weight>> {
            Log.d("Repository ", "getItems: $filterStart, $filterEnd")
            if ((filterStart != 0L) && (filterEnd == 0L)) return dao.getItemsGreaterThan(filterStart)
            else if ((filterStart == 0L) && (filterEnd != 0L)) return dao.getItemsLessThan(filterEnd)
            else if ((filterStart != 0L) && (filterEnd != 0L)) return dao.getItemsRange(filterStart, filterEnd)
            else return dao.getItems()
    }

有一次,我简化了一些事情并直接调用了 dao 函数,如下所示:

items = dao.getItemsLessThan(filterEnd)

甚至完全绕过存储库并直接从 ViewModel 调用相应的 dao 函数,但这也没有任何区别。然后是对应的dao函数,如下:

@Query("SELECT * from weight WHERE timestamp >=:start ORDER BY timestamp DESC")
abstract fun getItemsGreaterThan(start: Long): LiveData<List<Weight>>

标签: androidkotlinandroid-livedata

解决方案


推荐阅读