如何用 RxSwift 替换简单的委托协议?
How to replace a simple delegate protocol with RxSwift?
我正在寻找避免定义
的最佳方法
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 的新手)。
您试图传递有关所选项目的信息(如果我错了请纠正我)。
当前选择的项目
我们不关心选择/取消选择,我们只关心每时每刻选择的项目。
这可能是最常见的用例,因为您的用户(组件的用户)不需要具有本地状态。
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()
}
}
选择/取消选择事件
我们不关心选定的项目,我们只对事件本身感兴趣。
当您不需要项目但需要事件(例如 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()
}
}
两种方法都有效并且有利有弊。选择最适合你的。
我正在寻找避免定义
的最佳方法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 的新手)。
您试图传递有关所选项目的信息(如果我错了请纠正我)。
当前选择的项目
我们不关心选择/取消选择,我们只关心每时每刻选择的项目。
这可能是最常见的用例,因为您的用户(组件的用户)不需要具有本地状态。
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()
}
}
选择/取消选择事件
我们不关心选定的项目,我们只对事件本身感兴趣。
当您不需要项目但需要事件(例如 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()
}
}
两种方法都有效并且有利有弊。选择最适合你的。