Android ViewModel转换地图无法正常工作

时间:2019-09-10 19:44:18

标签: android kotlin android-livedata

我有一个带按钮的视图-

我的查看代码-

private val viewModel: MyViewModel by viewModel()

    override fun onCreateView(...): View? {
        //Button click
        view.getMyData.setOnClickListener {
            viewModel.onGetDataClicked.observe(this, Observer {
            view?.progressBar?.isVisible = it.loading
            view?.description?.text = it.data.value
        })
        }
        return view
    }

我的视图模型代码-

val viewState = MyViewState()

    val onGetDataClicked =
        Transformations.map(myDomain.getData(MyAction.GetMyDataAction)) {
            when (it) {
                is MyResult.Loading -> viewState.copy(loading = true, error = null)
                is MyResult.Success -> viewState.copy(
                    loading = false,
                    data = it.data,
                    error = null
                )
                is MyResult.Error -> viewState.copy(
                    loading = false,
                    error = it.error
                )
                else -> viewState.copy(loading = false)
            }
        }

这是MyViewState()的代码-

data class MyViewState(
    val loading: Boolean = false,
    val data: MyModel = MyModel(),
    val error: MyResult.ErrorType? = null
) : ViewState

当我打开应用程序并单击按钮时,调用转到viewmodel,然后从那里转到域,然后观察我的数据。但是在第二次单击按钮时,我的视图根本没有调用viewmodel。可能是什么问题?

2 个答案:

答案 0 :(得分:1)

问题是,如果您未在实时数据上注册任何观察者它不会触发。因此,您无法在viewModel上调试或查看它。

答案 1 :(得分:0)

在您的view.getMyData.setOnClickListener中,您仅观察到viewModel.onGetDataClicked并没有触发对myDomain.getData的新呼叫。您需要一种方法来触发每次用户点击的域功能。

override fun onCreateView(...): View? {

     onGetDataClicked.observe(this, Observer {
        view?.progressBar?.isVisible = it.loading
        view?.description?.text = it.data.value
     })

    view.getMyData.setOnClickListener {
       getDataFromDomain()
    }

    return view
}

val onGetDataClicked = MediatorLiveData<MyViewState>()

fun getDataFromDomain(){
    onGetDataClicked.addSource(myDomain.getData(MyAction.GetMyDataAction)){
        when (it) {
            is MyResult.Loading -> viewState.copy(loading = true, error = null)
            is MyResult.Success -> viewState.copy(
                loading = false,
                data = it.data,
                error = null
            )
            is MyResult.Error -> viewState.copy(
                loading = false,
                error = it.error
            )
            else -> viewState.copy(loading = false)
        }
    }
    )
}

更新
另一种解决方案是使用Transformation.switchMap。在此解决方案中,我们将创建一个LiveData来将点击事件转换为可观察的事件(将其命名为clickLiveData)。 并在onCreateView中设置一个点击监听器以更新clickLiveData。 另一个LiveData可以观察clickLiveData并执行switchMap:

val clickLiveData = MutableLiveData<Any>()

val dataFromDomainLiveData = Transformations.switchMap(clickLiveData){
    Transformations.map(myDomain.getData(MyAction.GetMyDataAction)) {
        when (it) {
            is MyResult.Loading -> viewState.copy(loading = true, error = null)
            is MyResult.Success -> viewState.copy(
                loading = false,
                data = it.data,
                error = null
            )
            is MyResult.Error -> viewState.copy(
                loading = false,
                error = it.error
            )
            else -> viewState.copy(loading = false)
        }
    }
}



override fun onCreateView(...): View? {

    view.getMyData.setOnClickListener {
       clickLiveData.value = Any()
    }

    viewModel.dataFromDomainLiveData.observe(this, Observer {
        view?.progressBar?.isVisible = it.loading
        view?.description?.text = it.data.value
    })        


    return view
}