สร้าง ViewModel ที่มี Dependency ส่วนหนึ่งของ Android Jetpack
ViewModel สามารถใช้ทรัพยากร Dependency เป็นพารามิเตอร์ในตัวสร้างได้ตามแนวทางปฏิบัติแนะนำของการแทรก Dependency โดยส่วนใหญ่จะเป็นประเภท
จากชั้นโดเมนหรือข้อมูล เนื่องจากเฟรมเวิร์กมี ViewModel จึงต้องใช้กลไกพิเศษในการสร้างอินสแตนซ์ของ ViewModel กลไกดังกล่าวคืออินเทอร์เฟซ ViewModelProvider.Factory มีเพียงการใช้งาน
ของอินเทอร์เฟซนี้เท่านั้นที่สามารถสร้างอินสแตนซ์ ViewModel ในขอบเขตที่ถูกต้องได้
ViewModel ที่มี CreationExtras
หากViewModelคลาสได้รับทรัพยากร Dependency ในตัวสร้าง ให้ระบุ Factory ที่ใช้ViewModelProvider.Factoryอินเทอร์เฟซ
แทนที่ฟังก์ชัน create(Class<T>, CreationExtras) เพื่อระบุอินสแตนซ์ใหม่ของ ViewModel
CreationExtras ช่วยให้คุณเข้าถึงข้อมูลที่เกี่ยวข้องซึ่งช่วย
สร้างอินสแตนซ์ ViewModel รายการคีย์ที่เข้าถึงได้จากส่วนพิเศษมีดังนี้
| คีย์ | ฟังก์ชันการทำงาน |
|---|---|
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY |
ให้สิทธิ์เข้าถึงคีย์ที่กำหนดเองที่คุณส่งไปยัง ViewModelProvider.get() |
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY |
ให้สิทธิ์เข้าถึงอินสแตนซ์ของคลาส Application |
SavedStateHandleSupport.DEFAULT_ARGS_KEY |
ให้สิทธิ์เข้าถึงกลุ่มอาร์กิวเมนต์ที่คุณควรใช้เพื่อสร้าง SavedStateHandle |
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY |
ให้สิทธิ์เข้าถึง SavedStateRegistryOwner ที่ใช้สร้าง ViewModel |
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY |
ให้สิทธิ์เข้าถึง ViewModelStoreOwner ที่ใช้สร้าง ViewModel |
หากต้องการสร้างอินสแตนซ์ใหม่ของ SavedStateHandle ให้ใช้ฟังก์ชัน
CreationExtras.createSavedStateHandle()
และส่งไปยัง ViewModel
CreationExtras ที่มี APPLICATION_KEY
ตัวอย่างต่อไปนี้แสดงวิธีระบุอินสแตนซ์ของ ViewModel ที่ใช้ repository ที่กำหนดขอบเขตไว้ที่คลาส Application และ SavedStateHandle เป็นทรัพยากร Dependency
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// ViewModel logic
// ...
// Define ViewModel factory in a companion object
companion object {
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
val savedStateHandle = createSavedStateHandle()
val myRepository = (this[APPLICATION_KEY] as MyApplication).myRepository
MyViewModel(
myRepository = myRepository,
savedStateHandle = savedStateHandle
)
}
}
}
}
จากนั้นคุณจะใช้ Factory นี้เมื่อเรียกข้อมูลอินสแตนซ์ของ ViewModel ได้
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
modifier: Modifier = Modifier,
viewModel: MyViewModel = viewModel(factory = MyViewModel.Factory)
) {
// ...
}
ส่งพารามิเตอร์ที่กำหนดเองเป็น CreationExtras
คุณส่งการอ้างอิงไปยัง ViewModel ผ่าน CreationExtras ได้โดยการสร้างคีย์ที่กำหนดเอง
ซึ่งจะเป็นประโยชน์หาก ViewModel ขึ้นอยู่กับออบเจ็กต์ที่เข้าถึงไม่ได้ผ่านคลาส Application และ APPLICATION_KEY ตัวอย่างของ
กรณีนี้คือเมื่อสร้าง ViewModel ภายในโมดูล Kotlin
Multiplatform และจึงไม่มีสิทธิ์เข้าถึงการอ้างอิงของ Android
ในตัวอย่างนี้ ViewModel จะกำหนดคีย์ที่กำหนดเองและใช้คีย์ดังกล่าวใน
ViewModelProvider.Factory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
) : ViewModel() {
// ViewModel logic
// Define ViewModel factory in a companion object
companion object {
// Define a custom key using the factory function
val MY_REPOSITORY_KEY = CreationExtras.Key<MyRepository>()
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
// Get the dependency in your factory
val myRepository = this[MY_REPOSITORY_KEY] as MyRepository
MyViewModel(
myRepository = myRepository,
)
}
}
}
}
คุณสามารถสร้างอินสแตนซ์ ViewModel ด้วย CreationExtras.Key ได้โดยตรงใน
Composables
import androidx.lifecycle.viewmodel.MutableCreationExtras
import androidx.lifecycle.viewmodel.compose.viewModel
// ...
@Composable
fun MyApp(myRepository: MyRepository) {
val extras = MutableCreationExtras().apply {
set(MyViewModel.MY_REPOSITORY_KEY, myRepository)
}
val viewModel: MyViewModel = viewModel(
factory = MyViewModel.Factory,
extras = extras,
)
}
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับ ViewModel และทรัพยากร Dependency ได้ที่แหล่งข้อมูลเพิ่มเติมต่อไปนี้
เอกสารประกอบ
ดูเนื้อหา
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- โมดูลสถานะที่บันทึกไว้สำหรับ ViewModel
- บันทึกสถานะ UI