Ինչպես մշակել MVI ճարտարապետությունում այն իրադարձությունները, որոնք պահպանում անհրաժեշտ չեն?
sobes.tech AI
Պատասխան AI-ից
Միայն մեկ անգամ տեղի ունեցող իրադարձությունների (օրինակ, տոստի ցուցադրում, նավիգացիա) մշակման համար MVI-ում, որոնք չպետք է վերականգնեն View-ը կամ պահպանվեն վիճակում, օգտագործվում են տարբեր մոտեցումներ:
-
Side Effects (SingleLiveEvent / Channels):
Հատուկ մեխանիզմ՝ իրադարձությունների ուղարկման համար ViewModel-ից View-ին:
SingleLiveEvent(հին նախագծերում կամandroidx.lifecycle:lifecycle-livedata-ktxգրադարաններում), կամChannelFlow-ից (համաշխարհային նախագծերում): Նրանք երաշխավորում են, որ իրադարձությունը կօգտագործվի միայն մեկ անգամ:// ViewModel՝ Flow և Channel-ով import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.receiveAsFlow import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch class MyViewModel : ViewModel() { private val _sideEffect = Channel<SideEffect>(Channel.BUFFERED) val sideEffect = _sideEffect.receiveAsFlow() fun doSomething() { // Բիզնես-լոգիկա... viewModelScope.launch { _sideEffect.send(SideEffect.ShowToast("Աշխատանքը հաջողությամբ կատարվեց!")) } } } sealed class SideEffect { data class ShowToast(val message: String) : SideEffect() object NavigateNext : SideEffect() } // View-ում (Fragment/Activity) հետևում ենք SideEffect-ին import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch class MyFragment : Fragment() { private val viewModel: MyViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewLifecycleOwner.lifecycleScope.launch { viewModel.sideEffect.collect { effect -> when (effect) { is SideEffect.ShowToast -> showToast(effect.message) SideEffect.NavigateNext -> navigateToNextScreen() } } } } private fun showToast(message: String) { // Տոստի ցուցադրման իրականացման կոդ } private fun navigateToNextScreen() { // Նավիգացիայի իրականացման կոդ } } -
Single Use Events in State:
Ավելի քիչ նախընտրելի տարբերակ, բայց երբեմն օգտագործվում է պարզ դեպքերում: Ավելացնում ենք նշան կամ դաշտ
UiState-ում, որը ցույց է տալիս միանգամից օգտագործվող իրադարձության առկայությունը: Իրադարձության մշակման ժամանակ View-ում, View-ը ուղարկում է նորIntentViewModel-ին՝ նշան/դաշտը զրոյացնելու համար: Սա կարող է բարդացնել տրամաբանությունը և հնարավոր է կրկնակի գործարկում առաջացնի սխալ կամ View-ի վերականգնման ժամանակ:// Օրինակ State՝ միանգամից օգտագործվող նշանով data class MyUiState( val data: List<Item> = emptyList(), val isLoading: Boolean = false, val showSuccessToast: Boolean = false // Նշան՝ միանգամից օգտագործվող իրադարձության համար ) // ViewModel-ում՝ հաջող գործարկումից հետո fun processSuccess() { _uiState.update { it.copy(showSuccessToast = true) } } // View-ում՝ showSuccessToast = true-ի դեպքում if (state.showSuccessToast) { showToast("Հաջողությամբ!") // Կարևոր է՝ ուղարկել Intent նշանը մաքրման համար viewModel.onToastShown() } // ViewModel-ում՝ նշանի մաքրում fun onToastShown() { _uiState.update { it.copy(showSuccessToast = false) } }
Ամենալավ և ժամանակակից Android-ով Flow և MVI-ով աշխատելու համար՝ օգտագործել Side Effects Channel-ով: Սա մաքուր, անվտանգ և կանխատեսելի լուծում է միանգամից օգտագործվող իրադարձությունների համար։