我有下一个用例:用户来到注册表单,输入姓名、电子邮件和密码,然后单击注册按钮。在该系统需要检查电子邮件是否被占用并根据显示错误消息或创建新用户...
我正在尝试使用 Room、ViewModel 和 LiveData 来做到这一点。这是我尝试学习这些组件的一些项目,但我没有远程 api,我会将所有内容存储在本地数据库中
所以我有这些类(class):
- 注册 Activity
- 注册 View 模型
- 用户
- 用户DAO
- 用户资料库
- 用户注册服务
所以我的想法是,将有一个监听器附加到注册按钮,它将调用 RegisterViewModel::register()
方法。
class RegisterViewModel extends ViewModel {
//...
public void register() {
validationErrorMessage.setValue(null);
if(!validateInput())
return;
registrationService.performRegistration(name.get(), email.get(), password.get());
}
//...
}
这就是基本思路,我还希望 performRegistration
返回给我新创建的用户。
最困扰我的是我不知道如何在服务中实现performRegistration
功能
class UsersRegistrationService {
private UsersRepository usersRepo;
//...
public LiveData<RegistrationResponse<Parent>> performRegistration(String name, String email, String password) {
// 1. check if email exists using repository
// 2. if user exists return RegistrationResponse.error("Email is taken")
// 3. if user does not exists create new user and return RegistrationResponse(newUser)
}
}
据我了解,UsersRepository
中的方法应该返回 LiveData,因为 UsersDAO
正在返回 LiveData
@Dao
abstract class UsersDAO {
@Query("SELECT * FROM users WHERE email = :email LIMIT 1")
abstract LiveData<User> getUserByEmail(String email);
}
class UsersRepository {
//...
public LiveData<User> findUserByEmail(String email) {
return this.usersDAO.getUserByEmail(email);
}
}
所以我的问题是如何实现 performRegistration()
函数以及如何将值传回 View 模型,然后如何将 Activity 从 RegisterActivity 更改为 MainActivity...
最佳答案
你可以使用我的辅助方法:
val profile = MutableLiveData<ProfileData>()
val user = MutableLiveData<CurrentUser>()
val title = profile.combineWith(user) { profile, user ->
"${profile.job} ${user.name}"
}
fun <T, K, R> LiveData<T>.combineWith(
liveData: LiveData<K>,
block: (T?, K?) -> R
): LiveData<R> {
val result = MediatorLiveData<R>()
result.addSource(this) {
result.value = block(this.value, liveData.value)
}
result.addSource(liveData) {
result.value = block(this.value, liveData.value)
}
return result
}
关于android - 如何一个接一个地合并两个实时数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50599830/