RxSwift - Observable 移除使用过的元素

Posted

技术标签:

【中文标题】RxSwift - Observable 移除使用过的元素【英文标题】:RxSwift - Observable removing used elements 【发布时间】:2017-10-20 22:30:53 【问题描述】:

在我的应用程序中,我有一组选择器。每个选择器都从服务中获取其值。

应用布局如下所示:

--------------------
-    picker 1      -
--------------------
-    add picker    -
--------------------

您可以点按add picker 来添加更多选择器,这些选择器放置在UIStackView 中。每个选择器都由其UIViewController 支持并拥有自己的viewModel,而容器视图控制器也有一个viewModel。

点击add picker 几次后,您会得到如下信息:

--------------------
-    picker 1      -
--------------------
-    picker 2      -
--------------------
-    picker 3      -
--------------------

当您点击每个选择器时,我会向用户显示一组选项。选项集来自一个 Web 服务,该服务由 View Model 包装在 Observable<OperationType> 中。

假设服务返回option 1option 2option 3,并且用户为第一个选择器选择option 1,我需要在第二个选择器打开时仅向用户提供option 2 和@987654333 @。

在我的主视图模型中,我有以下代码:

    var children = Variable<[ChildViewModel]>([])

    var allAvailableOperationTypes: Observable<[OperationType]> 
        return RequestManager.sharedInstance.rx
            .catalogues()
            .asObservable()
            .map  return $0.operationTypes 
        
    

然后我创建了一个新的Observable 来处理组合allAvailableOperationTypes 的最后一个值并“删除”已经选择的值。

类似:

var availableOperationTypes: Observable<[OperationType]> 
    return allAvailablePriceOperationTypes
        .map  (operationTypes) in
            operationTypes.filter  // keep those not used in children 
          
    

在视图控制器上,我将它绑定到按钮上:

    operationTypeButton.rx.tap
        .asObservable()
        .withLatestFrom(viewModel.availableOperationTypes)
        .subscribe(onNext:  [unowned self] (operationTypes) in
            self.presentPicker(forOperationTypes: operationTypes)
        )
        .addDisposableTo(disposeBag)

如果用户在第一个选择器上选择了一个值,然后添加了第二个,则第二个选择器将只包含“免费”选项。但是,第一个选择器仍会显示所有可用选项。

我想要实现的是让它变热,这样当用户点击选择器按钮时,它只显示他可以选择的选项。

【问题讨论】:

【参考方案1】:

如果我的理解正确,您希望您的 UIPickerView 显示所有可用选项,直到打开另一个选项,此时之前活动的选择器应该折叠为当前选择的值。这意味着您的选择器视图模型应该提供一个 Observable,告诉它们它们当前是否处于活动状态。然后选择器视图模型应该 filter 你的 allAvailableOperationTypes Observable,这是你应该绑定你的选择器。

这里的要点是,选择器的值也应该绑定到 Observable,而不是静态设置。从您的示例中不清楚是否已经是这种情况。

【讨论】:

ChildViewModel 有一个 Variable 存储当前值,所以我有一个 observable。至于选择器,之前的选择器仍然“活着”。假设我从 3 个可用选项开始,第一个选择器选择 1,第二个选择 2,如果我再次点击第一个选择器,我希望能够选择 3。

以上是关于RxSwift - Observable 移除使用过的元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 Observable 绑定 BehaviorRelay - RxSwift

RxSwift 对一个 observable 的多个订阅

如何从使用 RxSwift 返回 Observable 的服务中获取值

RxSwift:延迟 observable 直到另一个 observable 完成?

RxSwift - 一个 Observable 中的多个 Observable 值

Observable 的 RxSwift 用途