代码之家  ›  专栏  ›  技术社区  ›  Mateusz Hermanowicz

数据存储-流no在更改后发出新值

  •  0
  • Mateusz Hermanowicz  · 技术社区  · 3 年前

    我无法接收数据存储中的更改。在主屏幕上的设置中更改数据库模式后,应用程序应观察另一个数据源。

    @Singleton
    class SettingsRepositoryImpl @Inject constructor(
        @ApplicationContext private val context: Context
    ) : SettingsRepository {
        private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")
    
     override val databaseMode: Flow<String>
            get() =
                context.dataStore.data.map { preferences ->
                    preferences[DATABASE_MODE_KEY] ?: DatabaseMode.LOCAL.name
                }.distinctUntilChanged()
    
    /// Viewmodel ->
    viewModelScope.launch(Dispatchers.Default) {
                observeDatabaseModeUseCase().collect { databaseMode ->
                    observeAllProductsUseCase(databaseMode).map { products ->
                        getFilteredProductListUseCase(
                            products,
                            filterProductDataState.value.filterProduct
                        )
                    }.collect {
                        _uiState.value = MyPantryProductsUiState.Loaded(
                            MyPantryModel(
                                groupsProduct = getGroupProductListUseCase(it),
                                loadingVisible = false
                            )
                        )
                    }
                }
            }
    

    我试过了所有的调度员。我不知道为什么它在

    1 回复  |  直到 3 年前
        1
  •  0
  •   Tenfour04    3 年前

    你正在收集另一个流的收集块中的无限流。因此,当外流的第一个项目被发射时,它开始永远收集内流,而外流的第二个项目永远无法发射。使用 flatMapLatest 相反这将使它在第一个流发出新项目时中断第二个流。

    //In ViewModel init:
    observeDatabaseModeUseCase()
        .flatMapLatest { databaseMode ->
            observeAllProductsUseCase(databaseMode)
        }.map { products ->
            getFilteredProductListUseCase(
                products,
                filterProductDataState.value.filterProduct
            )
        }.onEach {
            _uiState.value = MyPantryProductsUiState.Loaded(
                MyPantryModel(
                    groupsProduct = getGroupProductListUseCase(it),
                    loadingVisible = false
                )
            )
        }
        .flowOn(Dispatchers.Default) // probably unnecessary since you don't seem to be doing blocking work.
        .launchIn(viewModelScope)
    

    你没有展示什么 _uiState 是,但您可以使用使其成为StateFlow stateIn 以简化您的代码。