【问题标题】:Proper way to update LiveData from the Model?从模型更新 LiveData 的正确方法?
【发布时间】:2021-01-23 22:33:34
【问题描述】:

使用 Android 更新视图的“正确”方法似乎是 LiveData。但我无法确定将其连接到模型的“正确”方式。我见过的大多数文档都显示连接到返回 LiveData 对象的 Room。但是(假设我没有使用 Room),在我的模型中返回一个 LiveData 对象(它是“生命周期感知的”,因此特定于 Android 的活动/视图框架)似乎违反了关注点分离?

这是一个 Activity 的示例...

class MainActivity: AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_activity);

        val viewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        val nameText = findViewById<TextView>(R.id.nameTextBox)

        viewModel.getName().observe(this, { name ->
            nameText.value = name
        })
    }
}

还有 ViewModel...

class UserViewModel(): ViewModel() {
    private val name: MutableLiveData<String> = MutableLiveData()

    fun getName() : LiveData<String> {
        return name
    }
}

但是我如何在不将专为特定框架设计的“生命周期感知”对象放入我的模型 (LiveData) 的情况下将其连接到我的模型...

class UserModel {
    val uid
    var name

    fun queryUserInfo() {
        /* API query here ... */
        val request = JSONObjectRequest( ...
            { response ->
                if( response.name != this.name ) {
                    this.name = response.name
                    /* Trigger LiveData update here somehow??? */
                }
            }
        )
    }
}

我想我可以在我的模型中放置一个 Observable 对象,然后使用它来触发 ViewModel 中 LiveData 的更新。但是不要找到任何其他人说这是“正确”的做法的地方。或者,我可以从模型中的 Observable 对象实例化 ViewModel 中的 LiveData 对象吗?

或者我只是在想这个错误还是我错过了什么?

【问题讨论】:

  • 看一下下一页的所有图片,你应该会更容易理解viewmodels-and-livedata-patterns-antipatterns
  • 那么,您的答案似乎是在模型中包含 LiveData?在模型中声明的具有“生命周期感知”组件(接收 LifeCycleOwner 对象)实际上并不违反“关注点分离”理念?
  • 不,保持模型清洁。创建用于加载数据的存储库(来自 api 或房间)并在 ViewModel 中观察 LiveData(来自 repo)...检查下面的答案...

标签: android mvvm android-livedata


【解决方案1】:

这是来自官方文档。检查代码中的 cmets...

UserModel 应该保持干净

class UserModel {
    private val name: String,
    private val lastName: String
}

创建存储库以从网络捕获数据

class UserRepository {
   private val webservice: Webservice = TODO()
   
   fun getUser(userId: String): LiveData<UserModel > {
       
       val data = MutableLiveData<UserModel>() //Livedata that you observe

       //you can get the data from api as you want, but it is important that you 
       //update the LiveDate that you will observe from the ViewModel 
       //and the same principle is in the relation ViewModel <=> Fragment

       webservice.getUser(userId).enqueue(object : Callback<UserModel > {
           override fun onResponse(call: Call<User>, response: Response<UserModel >) {
               data.value = response.body() 
           }
           // Error case is left out for brevity.
           override fun onFailure(call: Call<UserModel >, t: Throwable) {
               TODO()
           }
       })
       return data  //you will observe this from ViewModel
   }
}

下面的图片应该向你解释一切的样子

更多详情请查看:

https://developer.android.com/jetpack/guide

viewmodels-and-livedata-patterns-antipatterns

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多