如果我通知操作已完成,我应该使用 PublishSubject 吗?
Should I use a PublishSubject if I am notifying an action is complete?
我正在学习 Viper
w/ RxSwift
。
我想通知我的 Presenter
我的 ViewController
中调用了 viewDidLoad
。
为此,我有以下内容:
class LoginPresenter {
weak var view: LoginView?
var interactor: LoginUseCase?
var router: LoginRouter?
private(set) var viewDidLoad = PublishSubject<Void>()
private lazy var disposeBag = DisposeBag()
required init(view: LoginView?, interactor: LoginUseCase?, router: LoginRouter?) {
self.view = view
self.interactor = interactor
self.router = router
viewDidLoad
.subscribe(onNext: { _ in
// do something on viewDidLoad
}).disposed(by: disposeBag)
}
}
class LoginViewController: UIViewController {
var presenter: LoginPresenter?
override func viewDidLoad() {
super.viewDidLoad()
presenter?.viewDidLoad.onNext(())
}
}
加载我的视图后,我将调用 presenter?.viewDidLoad.onNext(())
然后我可以在演示者中触发任何操作,例如呼叫我的 router
以确保导航已配置或我的 interactor
.
我应该为此使用 PublishSubject
吗?或者 RxSwift
有更适合的类型吗?
我觉得这种方法意味着我最终会得到类似
的东西
viewDidLoad
.subscribe(onNext: { _ in
self.router?.viewDidLoad.onNext(())
}).disposed(by: disposeBag)
嗯...Presenter 的工作是收集用户操作,我不确定我们是否应该将 viewDidLoad 视为 user 操作。并且在任何情况下,线框(处理路由)都不需要知道何时首先调用 viewDidLoad;它的工作是呈现新屏幕,您不能在 viewDidLoad 中呈现屏幕。
也就是说,您可以在 ViewController 的演示者 didSet 中设置您的连接:
final class ViewController: UIViewController {
var presenter: Presenter? {
didSet {
guard let presenter = presenter else { viewDidLoadDisposable.dispose(); return }
viewDidLoadDisposable.disposable = rx.methodInvoked(#selector(viewDidLoad))
.map { _ in }
.bind(to: presenter.viewDidLoad)
}
}
let viewDidLoadDisposable = SerialDisposable()
deinit {
viewDidLoadDisposable.dispose()
}
}
final class Presenter {
let viewDidLoad = PublishSubject<Void>()
}
不过一般来说,presenter 和 viewController 元素通常是在 viewDidLoad 中绑定在一起的,所以上面的代码给人一种很不自然的感觉。
此外,Observables、Subjects 和 DisposeBag 应该 而不是 var
,请改用 let
。那是函数式反应式编程的“函数式”部分。
我正在学习 Viper
w/ RxSwift
。
我想通知我的 Presenter
我的 ViewController
中调用了 viewDidLoad
。
为此,我有以下内容:
class LoginPresenter {
weak var view: LoginView?
var interactor: LoginUseCase?
var router: LoginRouter?
private(set) var viewDidLoad = PublishSubject<Void>()
private lazy var disposeBag = DisposeBag()
required init(view: LoginView?, interactor: LoginUseCase?, router: LoginRouter?) {
self.view = view
self.interactor = interactor
self.router = router
viewDidLoad
.subscribe(onNext: { _ in
// do something on viewDidLoad
}).disposed(by: disposeBag)
}
}
class LoginViewController: UIViewController {
var presenter: LoginPresenter?
override func viewDidLoad() {
super.viewDidLoad()
presenter?.viewDidLoad.onNext(())
}
}
加载我的视图后,我将调用 presenter?.viewDidLoad.onNext(())
然后我可以在演示者中触发任何操作,例如呼叫我的 router
以确保导航已配置或我的 interactor
.
我应该为此使用 PublishSubject
吗?或者 RxSwift
有更适合的类型吗?
我觉得这种方法意味着我最终会得到类似
的东西 viewDidLoad
.subscribe(onNext: { _ in
self.router?.viewDidLoad.onNext(())
}).disposed(by: disposeBag)
嗯...Presenter 的工作是收集用户操作,我不确定我们是否应该将 viewDidLoad 视为 user 操作。并且在任何情况下,线框(处理路由)都不需要知道何时首先调用 viewDidLoad;它的工作是呈现新屏幕,您不能在 viewDidLoad 中呈现屏幕。
也就是说,您可以在 ViewController 的演示者 didSet 中设置您的连接:
final class ViewController: UIViewController {
var presenter: Presenter? {
didSet {
guard let presenter = presenter else { viewDidLoadDisposable.dispose(); return }
viewDidLoadDisposable.disposable = rx.methodInvoked(#selector(viewDidLoad))
.map { _ in }
.bind(to: presenter.viewDidLoad)
}
}
let viewDidLoadDisposable = SerialDisposable()
deinit {
viewDidLoadDisposable.dispose()
}
}
final class Presenter {
let viewDidLoad = PublishSubject<Void>()
}
不过一般来说,presenter 和 viewController 元素通常是在 viewDidLoad 中绑定在一起的,所以上面的代码给人一种很不自然的感觉。
此外,Observables、Subjects 和 DisposeBag 应该 而不是 var
,请改用 let
。那是函数式反应式编程的“函数式”部分。