Как ввести модель просмотра с помощью коина?(для конкретного случая использования) - PullRequest
1 голос
/ 26 июня 2019

У меня есть общая модель просмотра для активности и ее фрагмент.

Мой аргумент модели представления должен быть передан при создании экземпляра из действия (onCreate только один раз)

viewModel =ViewModelProviders.of(this,
                                 NoteViewModelFactory(application!!,
                                                      uid = intent!!.getStringExtra("uid")!!))
                             .get(NoteViewModel::class.java)

Но из фрагмента мне не нужно передавать аргумент, поскольку я уверен, что у меня есть аргумент, переданный один раз.

viewModel = ViewModelProviders.of(activity!!).get(NoteViewModel::class.java)

В Koin я попытался сделать ниже.

val noteModule = module(override = true) {
    viewModel { (id: String) -> NoteViewModel(androidApplication(), id) }
}

в Активности:

private val viewModel: NoteViewModel by viewModel { parametersOf(intent!!.getStringExtra("uid")!!) }

во фрагменте:

private val viewModel: NoteViewModel by sharedViewModel()

Приложение завершилось с ошибкой ниже:

java.lang.RuntimeException: невозможно запустить действие ComponentInfo {com.andor.navigate.notepad / com.andor.navigate.notepad.listing.NotesActivity}: org.koin.core.error.InstanceCreationException: не удалось создать экземпляр для [Тип: Фабрика, primary_type: 'com.andor.navigate.notepad.core.NoteViewModel'] на android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2665) на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2726) на android.app.ActivityThread.-wrap12 (ActivityThread.java) на android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1477) на android.os.Handler.dispatchMessage (Handler.java:102) на android.os.Looper.loop (Looper.java:154) на android.app.ActivityThread.main (ActivityThread.java:6119) в java.lang.reflect.Method.invoke (родной метод) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:886) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:776) Вызвано: org.koin.core.error.InstanceCreationException: не удалось создать экземпляр для [Тип: Фабрика, primary_type: 'com.andor.navigate.notepad.core.NoteViewModel'] в org.koin.core.instance.DefinitionInstance.create (DefinitionInstance.kt: 61) в org.koin.core.instance.FactoryDefinitionInstance.get (FactoryDefinitionInstance.kt: 37) в org.koin.core.definition.BeanDefinition.resolveInstance (BeanDefinition.kt: 70) в org.koin.core.scope.Scope.resolveInstance (Scope.kt: 165)

Я не могу понять, как решить эту проблему с помощью KOIN.

П.С .: Я новичок в Коин Д.И.

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

Вы не должны передавать аргументы такого типа в ViewModel конструкторе.Вместо этого вы можете указать в onCreate() своей Деятельности, что вы установили это переданное значение в ViewModel.Поэтому, когда вы получите доступ к ViewModel в своем фрагменте, у вас наверняка будет уже установлено это значение.

class NoteViewModel (application: Application) : AndroidViewModel(application)
{
    var id:String = ""   
}

Ваш модуль koin:

val noteModule = module(override = true) {
    viewModel { NoteViewModel(androidApplication()) }
}

Активность:

class MainActivity : AppCompatActivity() {

    private val viewModel: NoteViewModel by viewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel.id = intent?.getStringExtra("uid")?: ""

        supportFragmentManager.beginTransaction().replace(R.id.container, MyFrag()).commit()
    }
}

Фрагмент:

class MyFrag : Fragment() {

private val viewModel: NoteViewModel by sharedViewModel()

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    // your value will be available here.
    return inflater.inflate(R.layout.activity_main, container, false)
}

}

0 голосов
/ 26 июня 2019

Что-то не так, когда вы запускаете koin в классе приложения? Я попробовал ваш код без каких-либо проблем. Я использую версию koin 2.0.1

class App : Application() {

    override fun onCreate() {
        super.onCreate()

        val noteModule = module(override = true) {
            viewModel { (id: String) -> NoteViewModel(androidApplication(), id) }
        }

        startKoin {
            androidContext(this@App)
            modules(
                noteModule
            )
        }
    }

}

Активность и фрагмент:

class MainActivity : AppCompatActivity() {

    private val viewModel: NoteViewModel by viewModel { parametersOf(intent!!.getStringExtra("uid")) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("NoteViewModel", "id: ${viewModel.id}")

        supportFragmentManager.beginTransaction().replace(R.id.main_root, Frag()).commit()
    }

}
class Frag : Fragment() {

    private val viewModel: NoteViewModel by sharedViewModel()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        Log.d("NoteViewModel", "id: ${viewModel.id}")
        return inflater.inflate(R.layout.activity_main, container, false)
    }
}

Просмотр модели класса:

class NoteViewModel (application: Application, val id: String) : AndroidViewModel(application)
...