如何将值从片段发送到视图模型(存储库)?
How to send values from fragment to viewmodel (Repository)?
我正在开发一个基于 MVVM 架构的应用程序,其中我有一个值,用户 select 在我必须在我在 API 调用请求中更新的片段上RepositoryImpl class 使用 LiveData,我该怎么做?
class Fragment1 : ScopedFragment(), KodeinAware {
override val kodein by closestKodein()
private val viewModelFactory: Fragment1ViewModelFactory by instance()
private lateinit var viewModel: Fragment1ViewModel
private var selected1 = ""
private var selected2 = ""
private var selected3 = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment1, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this, viewModelFactory)
.get(Fragment1ViewModel::class.java)
bindUI()
}
setSpinner1()
setSpinner2()
setButton.setOnClickListener {
val modalbottomSheetFragment = MyBottomSheetDialogFragment()
modalbottomSheetFragment.show(parentFragmentManager, modalbottomSheetFragment.tag)
}
}
private fun bindUI() = launch {
valueContainer.visibility = View.VISIBLE
val currentValue = viewModel.fragment1
currentValue.observe(viewLifecycleOwner, Observer {
if (it == null) return@Observer
value.text = it.Val
})
comboSelected = selected1 + selected2
}
comboSelected 是我必须传递给存储库的值,以便我可以获取 selected 值对的值。
存储库代码 -
class NameRepositoryImpl(
private val NameValueDao: NameValueDao,
private val NameNetworkDataSource: NameNetworkDataSource
) : NameRepository {
init {
NameNetworkDataSource.downloadedName.observeForever { newNameValue ->
persistFetchedNameValue(newNameValue)
}
}
private val value: Flow<NameResponseDB> = NameValueDao.getNameValue()
override suspend fun getCurrentValue() {
return withContext(Dispatchers.IO) {
initNameData()
}
}
override fun getCurrentNameValue(): Flow<NameResponseDB> {
return value
}
private fun persistFetchedNameValue(nameValue: NameResponse) {
GlobalScope.launch(Dispatchers.IO) {
NameValueDao.upsert(
NameResponseDB(
valueCode = NameValue.valueCode,
nameVal = NameValue.nameVal
)
)
}
}
private suspend fun initNameData() {
if (isFetchNameNeeded(ZonedDateTime.now().minusMinutes(30)))
fetchNameValue()
}
private suspend fun fetchNameValue() {
NameNetworkDataSource.fetchCurrentValue(valueCode = "**Need the combo Selected Value here**")
val value = NameNetworkDataSource.fetchCurrentValue(valueCode = "**Need the combo Selected Value here**")
}
}
我没有具体使用过 Kodein
,但我使用过 Dependency Injection
和 MVVM
,使用过 Koin
和 Dagger Hilt
,所以基本思路应该这里也是一样。
您需要向 viewModel
提供 repository
的实例,并从该函数 fetchNameValue
中删除 private
,以便 viewModel
可以调用这个 suspend fun
通过 viewmodelscope
。另外,viewModel
和 repository
不是一回事。您应该单独创建它们的逻辑。所以应该是这样的:
Fragment
private fun bindUI() = launch {
valueContainer.visibility = View.VISIBLE
val currentValue = viewModel.fragment1
currentValue.observe(viewLifecycleOwner, Observer {
if (it == null) return@Observer
value.text = it.Val
})
comboSelected = selected1 + selected2
viewModel.doSomething(comboSelected)
}
ViewModel
class MyVm(
private val repository: Repository // inject respository
): ViewModel() {
fun doSomething(value: String) {
viewModelScope.launch {
repository.fetchNameValue(value)
}
}
}
Repository
class Repository {
suspend fun fetchNameValue(nameValue: String) {
NameNetworkDataSource.fetchCurrentValue(valueCode = nameValue)
val value = NameNetworkDataSource.fetchCurrentValue(valueCode = nameValue)
}
}
如果您仍有疑问,请告诉我,我会尝试更新我的答案:)
我正在开发一个基于 MVVM 架构的应用程序,其中我有一个值,用户 select 在我必须在我在 API 调用请求中更新的片段上RepositoryImpl class 使用 LiveData,我该怎么做?
class Fragment1 : ScopedFragment(), KodeinAware {
override val kodein by closestKodein()
private val viewModelFactory: Fragment1ViewModelFactory by instance()
private lateinit var viewModel: Fragment1ViewModel
private var selected1 = ""
private var selected2 = ""
private var selected3 = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment1, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this, viewModelFactory)
.get(Fragment1ViewModel::class.java)
bindUI()
}
setSpinner1()
setSpinner2()
setButton.setOnClickListener {
val modalbottomSheetFragment = MyBottomSheetDialogFragment()
modalbottomSheetFragment.show(parentFragmentManager, modalbottomSheetFragment.tag)
}
}
private fun bindUI() = launch {
valueContainer.visibility = View.VISIBLE
val currentValue = viewModel.fragment1
currentValue.observe(viewLifecycleOwner, Observer {
if (it == null) return@Observer
value.text = it.Val
})
comboSelected = selected1 + selected2
}
comboSelected 是我必须传递给存储库的值,以便我可以获取 selected 值对的值。
存储库代码 -
class NameRepositoryImpl(
private val NameValueDao: NameValueDao,
private val NameNetworkDataSource: NameNetworkDataSource
) : NameRepository {
init {
NameNetworkDataSource.downloadedName.observeForever { newNameValue ->
persistFetchedNameValue(newNameValue)
}
}
private val value: Flow<NameResponseDB> = NameValueDao.getNameValue()
override suspend fun getCurrentValue() {
return withContext(Dispatchers.IO) {
initNameData()
}
}
override fun getCurrentNameValue(): Flow<NameResponseDB> {
return value
}
private fun persistFetchedNameValue(nameValue: NameResponse) {
GlobalScope.launch(Dispatchers.IO) {
NameValueDao.upsert(
NameResponseDB(
valueCode = NameValue.valueCode,
nameVal = NameValue.nameVal
)
)
}
}
private suspend fun initNameData() {
if (isFetchNameNeeded(ZonedDateTime.now().minusMinutes(30)))
fetchNameValue()
}
private suspend fun fetchNameValue() {
NameNetworkDataSource.fetchCurrentValue(valueCode = "**Need the combo Selected Value here**")
val value = NameNetworkDataSource.fetchCurrentValue(valueCode = "**Need the combo Selected Value here**")
}
}
我没有具体使用过 Kodein
,但我使用过 Dependency Injection
和 MVVM
,使用过 Koin
和 Dagger Hilt
,所以基本思路应该这里也是一样。
您需要向 viewModel
提供 repository
的实例,并从该函数 fetchNameValue
中删除 private
,以便 viewModel
可以调用这个 suspend fun
通过 viewmodelscope
。另外,viewModel
和 repository
不是一回事。您应该单独创建它们的逻辑。所以应该是这样的:
Fragment
private fun bindUI() = launch {
valueContainer.visibility = View.VISIBLE
val currentValue = viewModel.fragment1
currentValue.observe(viewLifecycleOwner, Observer {
if (it == null) return@Observer
value.text = it.Val
})
comboSelected = selected1 + selected2
viewModel.doSomething(comboSelected)
}
ViewModel
class MyVm(
private val repository: Repository // inject respository
): ViewModel() {
fun doSomething(value: String) {
viewModelScope.launch {
repository.fetchNameValue(value)
}
}
}
Repository
class Repository {
suspend fun fetchNameValue(nameValue: String) {
NameNetworkDataSource.fetchCurrentValue(valueCode = nameValue)
val value = NameNetworkDataSource.fetchCurrentValue(valueCode = nameValue)
}
}
如果您仍有疑问,请告诉我,我会尝试更新我的答案:)