【发布时间】:2020-12-08 05:10:57
【问题描述】:
我在我的项目中使用 RxSwift 和 Swinject。我绑定输入/输出的方式与 RxSwift 给出的示例并不完全相同。在RxExample/GitHubSignup 中,绑定是在init() 中完成的,对吧?但是我发现很难实现,因为我使用 Swinject+SwinjectStoryboard 对视图控制器进行依赖注入。因此,init() 不可用,因为实例化视图模型的是 Swinject 容器。那么,除了使用init()之外,还有没有办法将视图控制器和视图模型绑定在一起呢?
我在想我可以使用 var 而不是 let 作为输出 observables 并创建一个函数 bind(observables: [Observable]) 或者其他可以执行从输入到输出的绑定和转换的东西。但是因为它们将是 vars 而不是 let,这意味着我们似乎被允许在整个代码中更改绑定。与我们只使用 let 并将它们绑定到 init() 不同。而且,通过使用函数而不是初始化程序,我必须将依赖项存储到成员变量中。而如果我使用初始化器,我可以只转换 map 或 flatMap 内部的依赖关系。
还有一个问题。说,如果我有这个:
class MyViewController: UIViewController {
@IBOutlet weak var refreshButton: UIButton!
@IBOutlet weak var tableView: UITableView!
var viewModel: MyViewModel!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
viewModel = MyViewModel(refreshTap: refreshButton.rx.tap, dataProvider: ApiAdapter().getData)
}
private func setupEvents() {
viewModel.tableDTOs.bind(to: tableView.rx.items(
cellIdentifier: reuseId, cellType: TableViewCell.self)) { _, dto, cell in
cell.fill(with: dto)
}.disposed(by: disposeBag)
}
}
final class MyViewModel {
let tableDTOs: Observable<[TableDTO]>
init(refreshTap: Observable<Void>, dataProvider: () -> Observable<[TableDTO]>) {
tableDTOs = Observable.merge(.just(), refreshTap) //Merge with .just to emit at once for initial values
.flatMapLatest { dataProvider().asDriver() }
}
}
那么在这种情况下,如果dataProvider返回complete或error,disposable就会被处理掉,对吧?因此场景将无响应,因为 UI 已经未绑定。知道如何解决这个问题吗?
谢谢。
【问题讨论】: