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也可以。
您可以尝试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)
| 归档时间: |
|
| 查看次数: |
10009 次 |
| 最近记录: |