如何将用户酶范围范围范围范围

发布于 2025-01-30 13:02:05 字数 950 浏览 4 评论 0原文

我正在使用“一项功能一项活动”体系结构维护一个大型应用程序。

现在,我想对一个用户酶进行范围,所以只要活动就可以生存,但是

// koin module
scope<MyFeatureActivity> {
    viewModel { MyFeatureActivityViewModel() }
    viewModel { MyFeatureFragmentAViewModel(usecase = get()) }
    viewModel { MyFeatureFragmentBViewModel(usecase = get()) }
    scoped { MyFeatureUseCase() }
}

// fragments
class FeatureAFragment: AppCompatDialogFragment(){

    private val viewModel by viewModel<MyFeatureFragmentAViewModel>()

    ....
}

// activity
class MyFeatureActivity : ScopeActivity() { ... }

,这是不起作用的。从myFeatureActivity启动myFeatureFragmenta时,它会引发一个例外:

org.koin.core.error.NoBeanDefFoundException: 
|- No definition found for class:'MyFeatureAViewModel'. Check your definitions!

我在做什么错?

请注意:我不想只是跳过范围,然后使用户酶A 单个(或factory),因为它实际上仅存储与此活动相关的一些数据:我们在此功能中应保留数据,但在离开时被驳回。

I'm maintaining a large app (mostly) using a "one feature one activity"-architecture.

Now i'd like to scope a usecase, so it lives as long as the activity, something like this:

// koin module
scope<MyFeatureActivity> {
    viewModel { MyFeatureActivityViewModel() }
    viewModel { MyFeatureFragmentAViewModel(usecase = get()) }
    viewModel { MyFeatureFragmentBViewModel(usecase = get()) }
    scoped { MyFeatureUseCase() }
}

// fragments
class FeatureAFragment: AppCompatDialogFragment(){

    private val viewModel by viewModel<MyFeatureFragmentAViewModel>()

    ....
}

// activity
class MyFeatureActivity : ScopeActivity() { ... }

However, this doesn't work. When launching MyFeatureFragmentA from MyFeatureActivity it's throwing an Exception:

org.koin.core.error.NoBeanDefFoundException: 
|- No definition found for class:'MyFeatureAViewModel'. Check your definitions!

What am i doing wrong?

Please note: I would not like to just skip scopes and make the usecase a single (or a factory), since it actually stores some data relevant to only this activity: The data should be kept while we're in this feature, but dismissed when leaving it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

染墨丶若流云 2025-02-06 13:02:05

您需要为此设置活动范围和碎片范围。

完整的代码段:


val myFeatureModule = module {
  scope<MyFeatureActivity> {
    scoped { MyFeatureUseCase() } // `scoped{}` = singleton per activity
    viewModel { MyFeatureActivityViewModel() }
    viewModel { MyFeatureFragment1ViewModel(usecase = get()) }
    viewModel { MyFeatureFragment2ViewModel(usecase = get()) }
  }
}

// now declare both the activity and the fragment as `KoinScopeComponent`.
// have their scope using standard koin-based provided scopes (see below)
// this way, the fragment scope will extend activity scope and koin bindings will work

class MyFeatureActivity: AppCompatActivity(), KoinScopeComponent {

   override val scope: Scope by activityScope()

   // koin bindings now will work on the activity. for example:
   val viewModel by viewModel<MyFeatureActivityViewModel>()
   ...
}

class MyFeatureFragment1: Fragment(), KoinScopeComponent {
  override val scope: Scope by fragmentScope()

  // koin bindings now will work on the fragment
  //
  // you can use `by viewModel<ViewModelClassType>` to get a viewmodel lifecycled to this fragment, 
  // or you can use `by sharedViewModel<ViewModelClassType>` to get a viewmodel lifecycled to the host activity
  

  // example for private viewModel (no one else is holding a reference to it):
  val viewModel by viewModel<MyFeatureFragment1ViewModel>() // private VM for the fragment

  // example of a view-model that the host activity is holding.
  // you can communicate with the activity (using e.g. live-data) 
  // or communicate with other fragments inside this activity, 
  // by using this viewModel:
  val activityViewModel by sharedViewModel<MyFeatureActivityViewModel>()
  
  ...
}

you will need to set both activity scope and fragment scope for this.

complete code snippet:


val myFeatureModule = module {
  scope<MyFeatureActivity> {
    scoped { MyFeatureUseCase() } // `scoped{}` = singleton per activity
    viewModel { MyFeatureActivityViewModel() }
    viewModel { MyFeatureFragment1ViewModel(usecase = get()) }
    viewModel { MyFeatureFragment2ViewModel(usecase = get()) }
  }
}

// now declare both the activity and the fragment as `KoinScopeComponent`.
// have their scope using standard koin-based provided scopes (see below)
// this way, the fragment scope will extend activity scope and koin bindings will work

class MyFeatureActivity: AppCompatActivity(), KoinScopeComponent {

   override val scope: Scope by activityScope()

   // koin bindings now will work on the activity. for example:
   val viewModel by viewModel<MyFeatureActivityViewModel>()
   ...
}

class MyFeatureFragment1: Fragment(), KoinScopeComponent {
  override val scope: Scope by fragmentScope()

  // koin bindings now will work on the fragment
  //
  // you can use `by viewModel<ViewModelClassType>` to get a viewmodel lifecycled to this fragment, 
  // or you can use `by sharedViewModel<ViewModelClassType>` to get a viewmodel lifecycled to the host activity
  

  // example for private viewModel (no one else is holding a reference to it):
  val viewModel by viewModel<MyFeatureFragment1ViewModel>() // private VM for the fragment

  // example of a view-model that the host activity is holding.
  // you can communicate with the activity (using e.g. live-data) 
  // or communicate with other fragments inside this activity, 
  // by using this viewModel:
  val activityViewModel by sharedViewModel<MyFeatureActivityViewModel>()
  
  ...
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文