如何用RxSwift替换简单的委托协议?

问题描述 投票:0回答:1

我正在寻找避免定义的最佳方法

protocol SomeTableviewCellDelegate: class {
    func didSelectTopic(topic: RTopic)
}

并使用RxSwift代替。

我已经定义了

var didSelectTopic: Observable<RTopic> {
    return _didSelectTopic.asObservable()
}
private let _didSelectTopic = PublishSubject<RTopic>()

var didDeselectTopic: Observable<RTopic> {
     return _didDeselectTopic.asObservable()
}
private let _didDeselectTopic = PublishSubject<RTopic>()

我找不到发出主题的正确方法(我是RxSwift的新手)。

rx-swift
1个回答
1
投票

您试图传递有关所选项目的信息(如果我错了,请纠正我)。

Currently selected items

我们不关心选择/取消选择,我们只关心在每个时刻选择的项目。

这可能是最常见的用例,因为您的用户(组件用户)不需要具有本地状态。

protocol TopicSelectionProvider {
    var selectedTopicsStream: Observable<Set<RTopic>> { get }
}

class MyTableDelegate: NSObject, UITableViewDelegate {
    private var selectedTopics = BehaviourRelay<Set<RTopic>>([])
    ...
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        var selected = selectedTopics.value
        selected.insert(topics[indexPath.row])
        selectedTopics.accept(selected)
    }

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        var selected = selectedTopics.value
        selected.remove(topics[indexPath.row])
        selectedTopics.accept(selected)
    }
}

extension MyTableDelegate: TopicSelectionProvider {
    var selectedTopicsStream: Observable<Set<RTopic>> {
        return selectedTopics.asObservable()
    }
}

Selection / Unselection events

我们不关心选定的项目,我们只对自己的事件感兴趣。

当您不需要项目时,可以使用此用例,但可以使用事件(例如,对于api调用)。

enum TopicSelectionEvent {
    case select(RTopic)
    case deselect(RTopic)
}

protocol TopicSelectionProvider {
    var topicSelectionStream: Observable<TopicSelectionEvent> { get }
}

class MyTableDelegate: NSObject, UITableViewDelegate {
    private var topicSelection = PublishSubject<TopicSelectionEvent>()
    ...
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        topicSelection.onNext(.select(topics[indexPath.row]))
    }

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        topicSelection.onNext(.deselect(topics[indexPath.row]))
    }
}

extension MyTableDelegate: TopicSelectionProvider {
    var topicSelectionStream: Observable<TopicSelectionEvent> {
        return topicSelection.asObservable()
    }
}

两种方法都有效并且有利有弊。选择一个最适合你的。

© www.soinside.com 2019 - 2024. All rights reserved.