当前位置: 首页 > 知识库问答 >
问题:

MVVM: ViewModel逻辑需要数据库中的信息,但是如何等待数据呢?

相高谊
2023-03-14

我是MVVM新手,正在尝试如何组织我的应用程序。我制作了一个简化的登录应用程序来帮助解决问题。

我把应用程序分成几层:活动-

我理解该活动应该只处理用户界面工作。因此,LoginActivity通过EditText视图从用户那里获取用户名,显示成功和失败祝酒,启动下一个活动,等等。但要真正登录用户,则需要loginViewModel。调用login(username),以便ViewModel可以处理所有业务逻辑。

LoginViewModel需要检查用户是否已经存在于数据库中。但是ViewModel应该如何等待数据库结果呢?

  1. 观察LiveData在视图模型(当前ser.observe(LoginActivity.this,新的观察者
myViewModel.getUserByName(username).observe(this, new Observer<User>() {
            @Override
            public void onChanged(User userFromDatabase) {
                // If userFromDatabase is not null, login as this user
            }
        });

也许我在架构的结构上遗漏了一些东西
或者是否有一种从ViewModel访问数据库的技术
或者我读到关于添加另一个“模型”层的内容?还是服务<有这么多的技巧和选择,希望有人能解决问题。

干杯下面是代码:


后勤活动:

public void loginButtonClicked(View v){
        // TODO: Stub. Login user
        String msg = myViewModel.loginUser(splashUserInput.getText().toString());
        if(msg.isEmpty()){
            Intent intent = new Intent(this, DEFAULT_FIRST_ACTIVITY);
            startActivity(intent);
        } else {
            Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
        }
    }

LoginViewModel:newUser返回null,即使它确实存在于数据库中。

public String loginUser(String username) {
    if(username.isEmpty()) {
        // If empty user input
        return "Username field missing";
    } else if(currentUser.getValue() != null && username.equals(currentUser.getValue().getUsername())) {
        // If user is already logged on
        return null; // No errors
    } else {
        // Else if logging on to a different user
        User oldUser = currentUser.getValue();
        User newUser;


        newUser = localRepository.getUserByName(username).getValue();
        // newUser is null since the repository's background thread is still accessing the database.

        if(newUser == null) {
            return "Login Failed. Username does not exist.";
        } else {
            updateCurrentUser(oldUser, newUser);
            return null; // No errors
        }
    }
}

存储库:

public LiveData<User> getUserByName(String name) {
    return myDao.getUserByName(name);
}

MyDao:

@Query("SELECT * FROM user_table WHERE username = :username")
LiveData<User> getUserByName(String username);

共有1个答案

孙乐逸
2023-03-14

你的用例不需要LiveData,你可以简单地从道返回用户。比如,我的道:

@Query("SELECT * FROM user_table WHERE username = :username")
User getUserByName(String username);

存储库:

public User getUserByName(String name) {
return myDao.getUserByName(name);
}

只有在基础数据频繁更改并且我们希望进行相应更改时,才应该使用LiveData。

 类似资料:
  • 我正在为我的网站建立一个测试框架,我想完全将框架从测试中分离出来,问题是当我写一个测试时,有时断言需要时间,直到它可以是真的,例如,如果我在上传文件页面,当文件上传时,网站应该显示文件上传成功页面,但它需要很长时间,直到浏览器到达这个页面 我应该如何强制断言在返回结果之前等待一段时间? 一些代码可能会解释我目前的工作方式: 上传页面类 成功上传页面: 测试方法: 当我以这种方式编写测试时,尽管Is

  • 本章介绍如何从OrientDB命令行获取特定数据库的信息。 以下语句是命令的基本语法。 注 - 只有在连接到特定数据库后才能使用此命令,并且它将检索仅当前正在运行的数据库的信息。 示例 在这个例子中,我们将使用我们在前一章中创建的名为的数据库。 将从数据库中检索基本信息。 可以使用以下命令获取数据库信息。 如果成功执行上面命令,将获得以下输出。

  • info 获得数据库的信息.info()Return: [string]返回数据库相关信息 print_r($database->info());/*Array( [server] => Uptime: 5074 Threads: 1 Questions: 15 Slow queries: 0 Opens: 67 Flush tables: 1 Open tables

  • info 获得数据库的信息.info()Return: [string]返回数据库相关信息 print_r($database->info());/*Array( [server] => Uptime: 5074 Threads: 1 Questions: 15 Slow queries: 0 Opens: 67 Flush tables: 1 Open tables

  • 我有一个API,它返回的数据类型为_HttpClientResponse,因为我使用的是httpClient,我使用下面的 当我打印结果i/flatter(23708):字符串i/flatter(23708):{“结果”:[{“IPAddress”:“192.1.1.1”,“说明”:“Windows 2016 Server”},{“IPAddress”:“192.1.1.1”,“说明”:“Wind

  • DBMetas() xorm支持获取表结构信息,通过调用 engine.DBMetas() 可以获取到数据库中所有的表,字段,索引的信息。 TableInfo() 根据传入的结构体指针及其对应的Tag,提取出模型对应的表结构信息。这里不是数据库当前的表结构信息,而是我们通过struct建模时希望数据库的表的结构信息