android - 如何一个接一个地合并两个实时数据?

标签 android observer-pattern android-room android-architecture-components android-livedata

我有下一个用例:用户来到注册表单,输入姓名、电子邮件和密码,然后单击注册按钮。在该系统需要检查电子邮件是否被占用并根据显示错误消息或创建新用户...

我正在尝试使用 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/

相关文章:

android - 如何在android中使用异步任务进行音频流

android - 并非所有表都在 SQLite 数据库中创建

java - 如何有条件地处理 Observable 链中的错误?

Java Swing 和观察者模式

java - 我的 Room 出现 "foreign key mismatch"错误的原因是什么?

android - 更新数据库时 LiveData 列表不更新

android - Android 模拟器中的网络摄像头 : "Cannot start camera" and "Result too large"

haskell - 如何在使用惰性序列时观察进度?

javascript - 使用 ajax/jquery 的浏览器即时更新

android - 无法更新房间数据库项目