如何一个接一个地组合两个实时数据?

问题描述 投票:5回答:1

我有下一个用例:用户登录表格,输入姓名,电子邮件和密码,点击注册按钮。之后系统需要检查电子邮件是否被采用并基于该显示错误消息或创建新用户...

我试图使用Room,ViewModel和LiveData来做到这一点。这是我尝试学习这些组件的一些项目,我没有远程api,我会将所有内容存储在本地数据库中

所以我有这些课程:

  • RegisterActivity
  • RegisterViewModel
  • 用户
  • UsersDAO
  • UsersRepository
  • UsersRegistrationService

所以我的想法是将有一个监听器附加到注册按钮,它将调用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()函数以及如何将值传递回视图模型,然后如何将活动从RegisterActivity更改为MainActivity ...

android observer-pattern android-room android-architecture-components android-livedata
1个回答
8
投票

MediatorLiveData的帮助下,您可以组合来自多个来源的结果。这里有一个如何组合两个来源的例子:

class CombinedLiveData<T, K, S>(source1: LiveData<T>, source2: LiveData<K>, private val combine: (data1: T?, data2: K?) -> S) : MediatorLiveData<S>() {

private var data1: T? = null
private var data2: K? = null

init {
    super.addSource(source1) {
        data1 = it
        value = combine(data1, data2)
    }
    super.addSource(source2) {
        data2 = it
        value = combine(data1, data2)
    }
}

override fun <T : Any?> addSource(source: LiveData<T>, onChanged: Observer<T>) {
    throw UnsupportedOperationException()
}

override fun <T : Any?> removeSource(toRemote: LiveData<T>) {
    throw UnsupportedOperationException()
}
}

这是上面的要点,如果它是未来的更新:https://gist.github.com/guness/0a96d80bc1fb969fa70a5448aa34c215

© www.soinside.com 2019 - 2024. All rights reserved.