大家好~我是程式新手,想詢問遇到的問題
我在網站中找到有關於 MVVM 使用 api 的相關範例
https://givemepass.blogspot.com/2019/11/android-mvvm-koin.html?fbclid=IwAR15W9Zzd8GCojBJgK9aIoqWn5k55Zv-9boiujT2BIGyQFwvEmTkKBgfnic
範例中,將api設置為viewmodel並在activity中observe所獲取到的資料
class InfoViewModel(var infoRepository: InfoRepository) : ViewModel() {
private var userInfoLiveData = MutableLiveData<String>()
val loading = MutableLiveData<Boolean>()
fun getUserInfo(): LiveData<String> = userInfoLiveData
@SuppressLint("CheckResult")
fun callInfo() {
val result = StringBuffer()
infoRepository.loadInfo()
.subscribeOn(Schedulers.newThread())
.map {
val sb = StringBuffer()
it.forEach { post ->
sb.append(post.body)
sb.append("\n")
sb.append("---------------------\n")
}
result.append(sb.toString())
}
.observeOn(AndroidSchedulers.mainThread())
.compose(toggleLoading())
.subscribe({
userInfoLiveData.setValue(it.toString())
}, {
userInfoLiveData.setValue(result.toString())
})
}
private fun <T> toggleLoading(): SingleTransformer<T, T> {
return SingleTransformer { single ->
single
.doOnSubscribe { loading.value = true }
.doFinally { loading.value = false }
}
}
}
我有個疑問~
當我使用databinding的方式,將button的onclick設置在viewmodel中
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="@{() -> viewModel.goBackClicked()}"
android:textSize="16sp" />
我在該activity對應的viewModel中,要使用api viewmodel
class ActivityViewModel(private val infoViewModel: InfoViewModel) : ViewModel() {
fun conFirmClicked() {
infoViewModel. callInfo()
}
}
val myModule = module {
viewModel { InfoViewModel(get()) }
viewModel { ActivityViewModel(get()) }
}
但這樣不就違反了viewmodel單一職責原則
想了解當遇到這種情況時該如何解決~
Hi~
我認為你提出的問題的範圍有點廣,應該更完整的去提出你認為哪個區塊是違反單一職責原則。
另外,我個人認為在 Android 開發的框架下,其實有很多時候你在產出時要顧及這些原則的難度是更高的,建議不需要 100% 符合所有原則,但是大方向要維持。
譬如: 這個情況下你維持 ViewModel 單一職責的目的是甚麼? 我想大多數目標是想要把商業邏輯視為 ViewModel 的職責,那在維持這個大方向的前提下,如果有數據是需要散落在 View 或是其他區塊,我認為就不是開發主要關注的。
當然,如果他是個問題,未來可能會被放大,但是我認為在有這些想法時,不要執著在完美符合,而是先從大方向完善,未來隨著經驗增加,你就有更多想法來完善這些問題,到時候也很可能這對你來說根本不是問題。
回到問題本身,我看到的是:
InfoViewModel 被創建後,又被放入 ActivityViewModel,然後你的實際按鈕行為又放入 ActivityViewModel。
如果你想做的是
以這兩點來看,並不違反單一職責。
如果有興趣的話,可以看一下 Android 官方目前對於架構的專案,或許會有意外的收穫,不用執著在用了甚麼套件,先有一套對 MVVM 的理解,在慢慢隨著經驗調整就好。
供參: https://github.com/android/architecture-samples
看起來問題應該是把A viewmodel 放進 B viewmodel
我覺得如果你想要執行的按鈕行為是在ActivityViewModel內
那你應該是學他範例程式碼裡面
使用repo的概念 注入到你的ActivityViewModel
var infoRepository: InfoRepository
然後再在ActivityViewModel內實現你要的業務邏輯
而且你貼的範例是用koin來依賴注入了
所以應該不用擔心需要自己實例化viewmodel的問題