如何在模块中添加视图模型?

问题描述 投票:0回答:3

在Dagger中,如何将模型添加到Module中? 例如,我通过以下方式添加演示者:

@Module
class AboutModule(val appContext: Context) {

    @FragmentScope
    @Provides
    fun providePresenter(): AboutListContract.Presenter {
        return AboutListPresenter(appContext = appContext)
    }
}

现在我想添加我的视图模型,也带有 appContext。

class AboutViewModel(val appContext: Context): ViewModel() {

更新: 我可以像这样添加我的视图模型吗?

@Module

    class AboutModule(val appContext: Context) {

        @FragmentScope
        @Provides
        fun provideModel(model: AboutViewModel): ViewModel {
            return AboutViewModel(appContext = appContext)
        }
    }
android mvvm dagger-2 android-viewmodel
3个回答
1
投票

要从组件中检索 ViewModel 而不使用 Map 多重绑定,您可以执行以下操作:

@Singleton
@Component(modules=[...])
interface SingletonComponent {
    val aboutListViewModel: Provider<AboutListViewModel>
}

当您可以使用

@Inject constructor
时,这才有效:

// unscoped
class AboutListViewModel @Inject constructor(): ViewModel() {
}

因为现在你可以做:

class AboutListFragment: Fragment(R.layout.about_list_fragment) {
    private val viewModel by viewModels<AboutListViewModel>() {
        object: ViewModelProvider.Factory {
            override fun create(clazz: Class<ViewModel>) {
                return (requireActivity().application as MyApplication).component.aboutListViewModel.get()
            }
        }
    }
}

这可能看起来很俗气,但您可以将所有这些隐藏在扩展函数中

fun <T: ViewModel> Fragment.fragmentViewModels(viewModelCreator: SingletonComponent.() -> T) = viewModels<T> {
    object: ViewModelProvider.Factory {
        override fun create(clazz: Class<ViewModel>) {
            val component = requireActivity().application as MyApplication).component
            return viewModelCreator(component)
        }
    }
}        

因为现在你可以做

class AboutListFragment: Fragment(R.layout.about_list_fragment) {
    private val viewModel by fragmentViewModels<AboutListViewModel> { component ->
        component.aboutListViewModel().get()
    }
}

即使没有地图多重绑定,这也能工作。如果你需要

SavedStateHandle
,你需要AssistedInject,但如果你不想要这个,当Dagger-Hilt稳定时会更容易(然后它会像
@ViewModelInject
@Assisted
一样简单) ).


1
投票

我用下一个解决方案解决了我的问题:

@Module
class AboutModule(val appContext: Context) {
    
    @FragmentScope
    @Provides
    fun provideFactory(): AboutViewModelFactory {
        return AboutViewModelFactory(appContext)
    }
}

在片段中这样写:

class AboutFragment : BaseFragment(), OnItemClickListener {

    lateinit var viewModel: AboutViewModel
    @Inject lateinit var viewModelFactory: AboutViewModelFactory

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        injectDependencies()

        viewModel = ViewModelProviders
            .of(this, viewModelFactory)
            .get(AboutViewModel::class.java)
    }

    private fun injectDependencies() {
        activity?.let {
            DaggerAboutComponent.builder().aboutModule(AboutModule(it)).build().inject(this)
        }
    }
}

好建议:https://stackoverflow.com/a/60884492/6387618


0
投票

ViewModels 使用 Dagger 注入 多重绑定

参考这篇Medium文章: https://medium.com/chili-labs/android-viewmodel-injection-with-dagger-f0061d3402ff

context
可以通过在 AppModule 类中提供来注入。

© www.soinside.com 2019 - 2024. All rights reserved.