एक स्टेटफुल व्यूमॉडल

Mar 13 2023
आज मैं आपके साथ एक आसान व्यूमोडेल वर्ग संस्करण साझा करना चाहता हूं जिसे मैंने लिखा है और मैं थोड़ी देर के लिए उपयोग कर रहा हूं। व्यूमोडेल से राज्य का प्रबंधन और खुलासा करने के लिए कोटलिन्स के लोकप्रिय एपीआई स्टेटफ्लो का उपयोग कर सकते हैं।
Unsplash पर केली सिक्किमा द्वारा फोटो

आज मैं आपके साथ एक आसान व्यूमोडेल वर्ग संस्करण साझा करना चाहता हूं जिसे मैंने लिखा है और मैं थोड़ी देर के लिए उपयोग कर रहा हूं।

व्यूमोडेल से राज्य का प्रबंधन और खुलासा करने के लिए कोई भी कोटलिन्स के लोकप्रिय एपीआई StateFlow का उपयोग कर सकता है ।

आइए नीचे दिए गए डेटा वर्ग के साथ हमारे यूआई राज्य का प्रतिनिधित्व करें:

data class UiState(
    val isLoading: Boolean = false,
    val hasError: Boolean = false,
    val data: ScreenData? = null,
)

उपरोक्त राज्य को यूआई में बेनकाब करने के लिए हम एक वर्ग का उपयोग करते हैं जो व्यूमोडेल को बढ़ाता है:

class ScreenViewModel() : ViewModel() {

    private val _uiState = MutableStateFlow(UiState())
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()

    suspend fun fetchData() {
        _uiState.update { state ->
            state.copy(
                isLoading = true,
                hasError = false
            )
        }

        val fetchedData = fetchDataFromNetwork()
        val failed = fetchedData is Error
        val data = fetchedData as? Data

        _uiState.update { state ->
            state.copy(
                isLoading = false,
                hasError = failed,
                data = data,
            )
        }
    }

}

आइए आगे मान लें कि हमें एक और फ़ंक्शन की आवश्यकता है जो डेटा को अपडेट करेगा, तो हम कुछ लिखेंगे:

suspend fun updateData(newData: Data) {
    _uiState.update { state ->
        state.copy(
            isLoading = true,
            hasError = false
        )
    }

    val update = updateAndGetData(newData)
    val failed = update is Error
    val data = update as? Data

    _uiState.update { state ->
        state.copy(
            isLoading = false,
            hasError = failed,
            data = data,
        )
    }
}

जैसा कि आप में से कई लोगों ने शायद किया है, मैंने इस पैटर्न का कई बार उपयोग किया है। इसलिए मैंने एक विस्तारित जेनेरिक व्यूमोडेल लिखने का फैसला किया, मैंने इसे स्टेटफुल व्यू मॉडेल कहा:

open class StatefulViewModel<T>(initState: T): ViewModel() {

    private val _uiState = MutableStateFlow(initState)
    val uiState = _uiState.asStateFlow()

    protected fun updateState(f: T.() -> T) {
        _uiState.update(f)
    }

    protected fun updateState(newState: T) {
        _uiState.value = newState
    }

    protected val state: T
        get() = _uiState.value
}

इस नए वर्ग का उपयोग करते हुए, हमारे ऊपर लिखे गए ScreenViewModel को नीचे दिए अनुसार रिफैक्टर किया जा सकता है:

class ScreenViewModel : StatefulViewModel<UiState>(UiState()) {

    suspend fun fetchData() {
        updateState {
            copy(isLoading = true, hasError = false)
        }

        val fetchedData = fetchDataFromNetwork()
        val failed = fetchedData is Error
        val data = fetchedData as? Data

        updateState {
            copy(isLoading = false, hasError = failed, data = data)
        }
    }

    suspend fun updateData(newData: Data) {
        updateState {
            copy(isLoading = true, hasError = false)
        }

        val update = updateAndGetData()
        val failed = update is Error
        val data = update as? Data

        updateState {
            copy(isLoading = false, hasError = failed, data = data)
        }
    }
    
}

मुझे आशा है कि आप StatefulViewModel वर्ग को उपयोगी पाएंगे और अपने अगले प्रोजेक्ट में इसका उपयोग करेंगे!