Создание экземпляра модели представления с помощью Activity в конструкторе с помощью компонента навигации - PullRequest
0 голосов
/ 20 июня 2020

все. У меня есть одна модель просмотра, которую я хочу использовать для всех фрагментов и активности, в которой они существуют. Проблема в том, что модели просмотра требуется ссылка на действие по созданию присоединенной к ней базы данных. И я использую Dagger2 для внедрения зависимости, а не для их создания.

Что я могу сделать с go по этому поводу? Я пробовал добавлять пакеты со ссылкой, но это не сработало. Я попытался запустить первый фрагмент с помощью navcontroller, но это тоже не сработало, так как я не могу передать ссылку на активность в аргументах. Я не могу передать ссылку через общую модель просмотра, потому что я не могу создать ее экземпляр без ссылки. Так что я полностью потерялся.

class HooskBankBranchesFragment(private val activity: AccountDetailsActivity) : androidx.fragment.app.Fragment() {

    @Inject
    lateinit var viewModel: AccountsProfileViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {



        return inflater.inflate(R.layout.hoosk_bank_branches_fragment, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        DaggerAccountsProfileComponent.builder()
            .accountsProfileModule(AccountsProfileModule(activity))
            .appComponent((activity?.application as HooskApp).component())
            .build().inject(this)


        rv_bankAccounts.layoutManager = LinearLayoutManager(activity)

        viewModel.state.observe(viewLifecycleOwner){
            when(it){
                is AccountsProfileViewModelState.OnDatabaseAccountsFetched -> rv_bankAccounts.adapter = BankDetailsRvAdapter(it.bankAccounts)
                is AccountsProfileViewModelState.Error -> Toast.makeText(activity, it.throwable.message, Toast.LENGTH_LONG).show()
            }
        }

        viewModel.getAccounts()


    }
}

Это класс Fragment, который невозможно создать, потому что я не могу передать ссылку на действие с помощью NavController.

class AccountsProfileViewModel(private val repository: AccountProfileRepository) : ViewModel() {


    private val _state = MutableLiveData<AccountsProfileViewModelState>()

    val state: LiveData<AccountsProfileViewModelState>
        get() = _state

    fun getAccounts() {
        viewModelScope.launch {
            try {
                _state.value = AccountsProfileViewModelState.OnDatabaseAccountsFetched(repository.getAccounts())
            } catch (error: Throwable) {
                _state.value = AccountsProfileViewModelState.Error(error)
            }
        }
    }

    fun getOnlineAccounts(accessCode: String) {
        viewModelScope.launch {
            try {
                _state.value = AccountsProfileViewModelState.OnOnlineAccountFetched(repository.getOnlineAccounts("Bearer $accessCode"))
            } catch (error: Throwable) {
                _state.value = AccountsProfileViewModelState.Error(error)
            }
        }
    }

    fun addAccount(account: BankAccountAPIModel) {
        viewModelScope.launch {
            try {
                repository.addAccount(account)
            } catch (error: Throwable) {
                _state.value = AccountsProfileViewModelState.Error(error)
            }
        }
    }

    fun getAccount(url: String){
        val sanitizer = UrlQuerySanitizer(url)
        viewModelScope.launch {
            try {
                val accessToken = repository.getAccessCode(sanitizer.getValue("code"))
                val onlineAccount = repository.getOnlineAccounts("Bearer " + accessToken.accessToken)
                _state.value = AccountsProfileViewModelState.OnOnlineAccountFetched(onlineAccount)

                repository.addAccount(onlineAccount)
                _state.value = AccountsProfileViewModelState.OnDatabaseAccountsFetched(repository.getAccounts())

            }catch (error: Throwable){
                _state.value = AccountsProfileViewModelState.Error(error)
            }
        }
    }

    fun getAccessCode(url: String) {
        val sanitizer = UrlQuerySanitizer(url)
        viewModelScope.launch {
            try {
                _state.value = AccountsProfileViewModelState.OnAccessTokenRetrieved(repository.getAccessCode(sanitizer.getValue("code")))
            } catch (error: Throwable) {
                _state.value = AccountsProfileViewModelState.Error(error)
            }
        }
    }


}



sealed class AccountsProfileViewModelState{
    object Loading : AccountsProfileViewModelState()
    data class Error(val throwable: Throwable): AccountsProfileViewModelState()
    data class OnAccessTokenRetrieved(val accessToken: AccessToken): AccountsProfileViewModelState()
    data class OnOnlineAccountFetched(val bankAccount: BankAccountAPIModel): AccountsProfileViewModelState()
    data class OnDatabaseAccountsFetched(val bankAccounts: List<BankAccountAPIModel>): AccountsProfileViewModelState()
}

Вот моя модель просмотра , Я не уверен, помогает ли это чему-нибудь.

То, что мне удалось сделать, что я сразу понял, было неправильным, - это создание модели представления дважды, одно было прикреплено к действию, а второе - к фрагменту. Которая обновила только фрагмент из базы данных после перезапуска приложения. Я понял, что тогда это было неправильно, так как я не мог наблюдать точную модель просмотра.

1 Ответ

0 голосов
/ 20 июня 2020

Я понял свою проблему.

        DaggerAccountsProfileComponent.builder()
            .accountsProfileModule(AccountsProfileModule(activity))
            .appComponent((activity?.application as HooskApp).component())
            .build().inject(this)

Я удалил ссылку в конструкторе и изменил AccountsProfileModule (activity) на:

        DaggerAccountsProfileComponent.builder()
            .accountsProfileModule(AccountsProfileModule(activity as AccountDetailsActivity))
            .appComponent((activity?.application as HooskApp).component())
            .build().inject(this)
```
...