【问题标题】:Android kotlin MVVM - can you call viewmodel inside recyclerview adapter?Android kotlin MVVM - 你可以在 recyclerview 适配器中调用 viewmodel 吗?
【发布时间】:2019-09-29 03:38:09
【问题描述】:

我有一个对象列表,每个对象都有自己的对象列表(有时也有一个列表)。

所以我有一个主要对象列表的回收视图。在主要对象的适配器内部,我为辅助对象列表创建了另一个 recyclerview 适配器。 (如果我得到一个有 3 个嵌套列表的对象,嵌套会继续下去)

我使用 MVVM 架构。我从 API 接收数据,因此我在 ViewModel 中定义 RxJava 调用(Disposable),然后在 Activity 中创建该 ViewModel 的实例并加载数据。

现在我的问题是,如何加载嵌套 recyclerview 列表的数据? viewModel 是 Activity 独有的,我不能在适配器内调用 viewModel(因为我使用 dagger 并且注入仅在 Activity 中有效)

数据示例:因此,通过这些示例,我将获得一个 Person 对象,在该对象内部有一个包含 Car 对象的列表,并且在该列表中还有另一个 Submodel 对象列表。

嵌套 json 对象:

{
    "personId": 1,
    "personName": "Bert",
    "personAge": 19,
    "isFemale": "false",
    "cars": [
                 {
            "carId": 1,
            "personId": 1,
            "carMake": "BWM",
            "model": "E36",
            "submodels": [{
                "submodelId": 1,
                "carId": 1,
                "submodelName": "335i"
            }, {
                "submodelId": 2,
                "carId": 1,
                "submodelName": "330d"
            }]
        }, {
            "carId": 2,
            "personId": 1,
            "carMake": "Porsche",
            "model": "911",
            "submodels": [{
                    "submodelId": 3,
                    "carId": 2,
                    "submodelName": "Carrera 4S"
                },
                {
                    "submodelId": 4,
                    "carId": 2,
                    "submodelName": "GT3 RS"
                }]
        }],
        "birthDate": "2000-06-28T00:00:00"

}

API接口:

@GET("persons/{id}")
fun getPerson(@Path("id) id: Int: Observable<Person>

PersonRepo:

  class PersonsRepository @Inject constructor(val apiInterface: ApiInterface) {
 fun getPersons(personId: Int): Observable<Person>{
   return apiInterface.getPerson(personId)
 }
}

PersonViewModel:

class PersonViewModel @Inject constructor(private val personRepositoy: PersonRepository) : ViewModel() {
  var personResult: MutableLiveData<Person> = MutableLiveData()
  var personError: MutableLiveData<String> = MutableLiveData()
  lateinit var personDisposable: Disposable

  fun personResult(): LiveData<Person> {
    return personResult
  }
  fun personError(): LiveData<String> {
    return personError
  }

  fun loadPerson(personId: Int) {
    personDisposable = personRepository
    .getPerson(personId)
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({
      personResult.postValue(it)
  }, {
      personError.postValue(it.message)
  })

  fun disposeElements(){
      if(::personDisposable.isInitialized && !personDisposable.isDisposed) {
            personDisposable.dispose()
        }
    }
}

模型如下所示: 人物模型:

data class Person (
  @Json(name = "personId")
  val personId: Int,

  @Json(name = "personName")
  val name: String,

  @Json(name = "personAge")
  val age: Int,

  @Json(name = "isFemale")
  val isFemale: Boolean,

  @Json(name = "cars")
  val cars: List<Car>

  @Json(name = "birthDate")
  val birthDate: GregorianCalendar

)

汽车:

data class Car(
  @Json(name = "carId")
  val carId: Int,

  @Json(name = "carMake")
  val carMake: String,

  @Json(name = "model")
  val model: String,

  @Json(name = "submodels")
  val submodels: List<SubModel>
)

子模型:

data class SubModel(
  @Json(name = "submodelId")
  val submodelId: Int,

  @Json(name = "carId")
  val carId: Int,

  @Json(name = "submodelName")
  val submodelName: String
)

【问题讨论】:

  • 您可以考虑通过删除不必要的代码来缩短问题...

标签: android mvvm kotlin android-recyclerview rx-java


【解决方案1】:

不知道匕首,但似乎纯粹的基于编译时声明的注入显然是一个限制,在这种情况下会导致错误的代码。 DI 不是解决所有问题的工具,它有时甚至会使事情变得更糟,尤其是在针对 JVM 实现时。

【讨论】:

  • 是的,它可能是,但它也有它的好处,现在用 Dagger 撤消一切为时已晚。另外,如果我不使用 dagger,我认为在适配器内部进行 API 调用仍然不是一个好主意,因为我使用的是 MVVM
  • 您不必撤消所有操作。试着去适应它。是否有可能在运行时注册和解析依赖项(例如 Container.register(foo))?这可能有助于获得灵活性。
猜你喜欢
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2020-07-08
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多