Допустима ли передача MutableLiveData другим ViewModels? - PullRequest
1 голос
/ 07 августа 2020

У меня есть сценарий, в котором два фрагмента (A и B) должны совместно использовать список объектов, который можно изменять с обоих экранов. Каждый фрагмент A и B имеет соответствующую ViewModel (A_ViewModel и B_ViewModel). Они содержат некоторые logi c о том, как общие данные видоизменяются.

Чтобы сохранить общие данные в такт, я создал AB_Flow_ViewModel, который имеет область действия и содержит эти общие данные, завернутые в MutableLiveData.

Я решил передать этот MutableLiveData объект дочерним фрагментам A и B в качестве параметра конструктора.

Я нигде не встречал такого подхода, но, похоже, он отлично работает для меня.

Есть ли у этого недостатки?

Это псевдокод моего решения:

// Navigation: (A ->  B)
class A() : Fragment() {

  private val viewModel: A_ViewModel ...

  override fun onViewCreated(
      view: View,
      savedInstanceState: Bundle?
  ) {
    super.onViewCreated(view, savedInstanceState)
    viewModel.sharedData.observe {
      ...
    }
  }

}


class A_ViewModel @Inject  constructor(
    val sharedData: MutableLiveData<List<Any>>
) : ViewModel() {

  fun changeSharedData(newSharedData: List<Any>) {
    sharedData.value = newSharedData
  }
}

@Module
class A_Module {

  @Provides
  @FragmentScoped
  fun provideSharedData(fragment: A) =
      fragment.activityViewModels<AB_Flow_ViewModel>().value.sharedData
}

class B() : Fragment() {

  private val viewModel: A_ViewModel ...

  override fun onViewCreated(
      view: View,
      savedInstanceState: Bundle?
  ) {
    super.onViewCreated(view, savedInstanceState)
    viewModel.sharedData.observe {
      ...
    }
  }
}

@Module
class B_Module {

  @Provides
  @FragmentScoped
  fun provideSharedData(fragment: B) =
      fragment.activityViewModels<AB_Flow_ViewModel>().value.sharedData
}


class B_ViewModel @Inject constructor(
    val sharedData: MutableLiveData<List<Any>>
) : ViewModel() {
  fun changeSharedData(newSharedData: List<Any>) {
    sharedData.value = newSharedData
  }
}

class AB_Flow_ViewModel() : ViewModel() {
  val sharedData = MutableLiveData<List<Any>>()
}

1 Ответ

1 голос
/ 07 августа 2020

Я настоятельно рекомендую не разделять MutableLiveData между двумя фрагментами, если вы получите ошибку, ее будет очень сложно отлаживать, потому что вы не будете знать, кто изменяет эти данные и где вызвать это странное состояние. Что мне нравится делать, так это хранить все мои MutableLiveData внутри ViewModel и предоставлять только LiveData для просмотра фрагментам / представлению. Каждое изменение, которое должно произойти с MutableLiveData, я делаю с помощью функции внутри ViewModel.

private val _sharedData = MutableLiveData<List<Any>>()
val sharedData: LiveData<List<Any>>
    get() = _sharedData

Я бы поместил забавную changeSharedData внутри AB_Flow_ViewModel и поместил все logi c в одну ViewModel вместо двух. Если logi c должен отличаться для FragA и FragB, я бы использовал два разных метода, которые изменят один и тот же LiveDdata

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...