เป็นไปได้ไหมที่จะส่ง ViewModel ไปยัง Fragment ในตัวสร้าง

ฉันใช้ Koin สำหรับ DI แต่ฉันกำลังพยายามลดการพึ่งพากรอบงาน DI ดังนั้นคำถามของฉันเกี่ยวกับส่วนประกอบสถาปัตยกรรม Android โดยทั่วไป

เป็นไปได้ที่จะจัดเตรียมอินสแตนซ์ของ ViewModel โดยผู้รับมอบสิทธิ์คุณสมบัติในส่วนย่อย แต่ทำให้เกิดการเชื่อมต่อระหว่างส่วนย่อยและกรอบงาน DI ดังนั้นฉันจึงคิดวิธีแก้ปัญหา: ส่ง ViewModel ไปยัง Fragment ในตัวสร้าง การใช้งานปัจจุบันกับ Koin มีลักษณะดังนี้:

val di = module {
    fragment {
        MyFragment(
            get<MyViewModel>(),
        )
    }
    viewModel {
        MyViewModel(
            get<MyDependency>(),
        )
    }
    //...
}

และมันก็ได้ผล แต่มีการจับเป็น เนื่องจาก ViewModel ถูกสร้างขึ้นก่อน Fragment จะไม่เป็นไปตามวงจรชีวิตของ Fragment และ onCleared() จะไม่ถูกเรียกเมื่อ Fragment ถูกทำลาย

ฉันจึงสงสัยว่าฉันจะทำให้มันทำงานอีกครั้งได้อย่างไร




คำตอบ (2)


จริงๆแล้วปัญหานี้ไม่เกี่ยวข้องกับ Koin เลย หากต้องการสร้าง ViewModel อย่างถูกต้อง (เชื่อมโยงกับวงจรชีวิต) คุณต้องมีการอ้างอิงถึง ViewModelProvider ซึ่ง สามารถสร้างได้โดยใช้ Fragment หรือ Activity

ดังนั้นคุณควรมีการอ้างอิงถึง Fragment หรือ Activity ก่อน นั่นทำให้ไม่สามารถส่ง ViewModel เป็นอาร์กิวเมนต์ตัวสร้างไปยังแฟรกเมนต์ได้

เพื่อลดการพึ่งพา Koin คุณสามารถรวมฟังก์ชันส่วนขยาย Koin viewModel() ไว้ในฟังก์ชันของคุณเองได้ เพื่อให้คุณสามารถสลับ DI ได้หากจำเป็น

person Aleksei Potapkin    schedule 23.04.2021
comment
จากสิ่งที่ฉันเห็น ViewModelProvider มีการอ้างอิงถึง ViewModelStoreOwner ซึ่งเป็นอินเทอร์เฟซ กิจกรรมและส่วนย่อยเป็นการใช้งานเริ่มต้นของอินเทอร์เฟซนี้ แต่ฉันเชื่อว่าโมดูล Koin (หรือขอบเขตหรืออย่างอื่นใน Koin) สามารถมีบทบาทเป็น ViewModelStoreOwner ได้ หรือฉันพลาดบางอย่างเกี่ยวกับการเชื่อมต่อ ViewModelProvider กับกิจกรรมและแฟรกเมนต์ - person oleg.semen; 23.05.2021
comment
แต่คุณต้องมี ViewModelStoreOwner เป็น lifecycleOwner หากคุณต้องการผูก ViewModel เข้ากับวงจรการใช้งานของกิจกรรม/แฟรกเมนต์ หรือจะไม่มีการเรียก onCleared() ที่เหมาะสมเมื่อกิจกรรมสิ้นสุดลง - person Aleksei Potapkin; 26.05.2021

ในระดับพื้นฐาน แฟรกเมนต์คือออบเจ็กต์ ดังนั้นคุณจึงสามารถส่งผ่านพารามิเตอร์ในตัวสร้างของแฟรกเมนต์ได้ อย่างไรก็ตาม นี่ไม่ใช่แนวปฏิบัติที่ดีและคุณควรหลีกเลี่ยงสิ่งนี้เสมอ เนื่องจาก Android เป็นระบบที่อิงตามเหตุการณ์ ดังนั้นคุณต้องประพฤติตนตามนั้น ปัญหาต่างๆ มากมายสามารถระบุได้เนื่องจากแนวปฏิบัติที่ไม่ดีนี้ แต่มาเน้นที่ปัญหาของคุณกันดีกว่า ภายใน เมธอด onCleared() ของโมเดลมุมมองถูกเรียกโดย viewModelStoreOwner ซึ่งถูกนำไปใช้โดยกิจกรรมและแฟรกเมนต์ ดังนั้น กิจกรรมหรือส่วนย่อยจึงต้องคำนึงถึงโมเดลมุมมองนี้ วิธีที่ง่ายที่สุดในการให้ความตระหนักดังกล่าวคือการใช้วิธีการขยาย viewModels ( https://developer.android.com/kotlin/ktx#fragment ) โดยจะเชื่อมโยงโมเดลมุมมองของคุณกับส่วนหรือกิจกรรมของคุณภายในโดยตรง อย่างไรก็ตาม ด้วยโซลูชันนี้ เราต้องพิจารณาอีกปัญหาหนึ่งซึ่งก็คือ วิธีที่เราฉีดอ็อบเจ็กต์อื่นๆ ของเรา (ที่เก็บข้อมูล กรณีการใช้งาน ฯลฯ) ลงในโมเดลมุมมองของเรา ในการดำเนินการนี้ เราจำเป็นต้องใช้โรงงานโมเดลมุมมองแบบกำหนดเอง ฉันไม่แน่ใจว่าส่วนนี้จำเป็นสำหรับ Koin ดังนั้นคุณสามารถดูที่ https://insert-koin.io/docs/reference/koin-android/viewmodel/

person M.ekici    schedule 13.03.2021
comment
หากคุณต้องการคำอธิบายทางเทคนิคเพิ่มเติม ฉันสามารถตอบได้ - person M.ekici; 14.03.2021