我可以在我的视图模型中创建一个实时数据观察器吗?或者我应该始终观察片段/活动?

Agu*_*ana 3 android kotlin android-livedata android-viewmodel android-architecture-components

我是 MVVM 新手。因此,我的片段/活动向服务器发出了 2 个请求,第一个请求的结果将用作第二个请求的输入参数。

因此,首先在我的片段中,当单击按钮时,我会发出请求以检查用户是否被禁止,如果没有,则该用户可以创建帖子。

所以首先我检查用户是否被禁止或没有在我的片段中使用此代码

class CreateEventFragment : Fragment() {

    lateinit var model: CreateEventViewModel


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        model = ViewModelProvider(this).get(CreateEventViewModel::class.java)

        button.setOnClickListener {
            model.checkIfUserIsBanned()
        }

    }


}
Run Code Online (Sandbox Code Playgroud)

这是视图模型

class CreateEventViewModel(application: Application) : AndroidViewModel(application) {

    val mUserIsBanned :MutableLiveData<Boolean> = UserClient.mUserIsBanned

    fun checkIfUserIsBanned(userID: String) {
        UserRepository.checkIfUserIsBanned(id)
    }


}
Run Code Online (Sandbox Code Playgroud)

这是客户端(为了简单起见,我跳过了存储库)

object UserClient {

    val mUserIsBanned = MutableLiveData<Boolean>()

    fun checkIfUserIsBanned(userID: String) {

        // perform networking, after getting the value then

        if (user.isBanned) {
            mUserIsBanned.postValue(true)
        } else {
            mUserIsBanned.postValue(false)
        }

    }



}
Run Code Online (Sandbox Code Playgroud)

这里的问题是,第二个请求需要第一个结果的结果,即mUserIsBanned需要检查用户是否没有被禁止,然后执行第二个请求(用户创建帖子)。我的问题是,我该把这个逻辑放在哪里?在视图模型中还是在我的片段中?

if (userIsBanned == false) {
   createPost()
}
Run Code Online (Sandbox Code Playgroud)

从我看到的教程来看,似乎实时数据总是在片段中观察到的。所以第一个选择是将逻辑放在片段中,如下所示

    model.mUserIsBanned.observe(viewLifecycleOwner, Observer { isBanned ->

        val userIsBanned = isBanned ?: return@Observer

        if (!userIsBanned) {
            model.createPost()
        }

    })
Run Code Online (Sandbox Code Playgroud)

可以将这样的代码检查放在片段中吗?

实际上我不需要观察 isBanned,我只需要检查一次

或者第二个选项是在视图模型中检查 userIsBanned 或不在视图模型中,但我不知道如何在视图模型中进行实时数据观察

还是我的方法全错了?我不确定是否使用这个 MVVM

请帮忙,java也可以。

Jee*_*ede 5

您可以尝试MediatorLiveData进行第二次手术。作用MediatorLiveData是,它为您的各种LiveData对象创建一个可监听的容器,并在任何底层/观察值发生变化时为您提供回调。

示例:假设LiveData<B>需要对 的任何值更改进行调用LiveData<A>,这里您可以将LiveData<B>其视为MediatorLiveData

所以声明为LiveData<B>

val bLiveData : LiveData<B> = MediatorLiveData<B>().apply {
    addSource(aLiveData) { aData ->
        value = convertADataToB(aData) //value is backing property for getValue()/setValue() method, use postValue() explicitly upon bg operation
    }
}
Run Code Online (Sandbox Code Playgroud)

对于您的情况,请将此代码放入您的ViewModel

val createPostLiveData: LiveData<Boolean> = MediatorLiveData<Boolean>().apply {
    addSource(mUserIsBanned) { flag ->
        if (!flag) {
            createPost() // Check whether you can return result from here and provide to this mediator livedata a value
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅MediatorLiveData