RxSwift.Что использовать для Observable <Void>? - PullRequest
3 голосов
/ 30 апреля 2019

Запись проекта на MVVM и попытка связать все с помощью RxSwift .К сожалению, мне не удалось найти правильный способ связывания действий.

Например, у меня есть таблица и простые ячейки с одной кнопкой - «Выбрать».

Для этих целейУ меня будет две модели представлений: ListViewModel & CellViewModel

ListViewModel будут создавать массив CellViewModel и должны будут подписаться на событие выбора (пользовательское событие).

Сейчас я использую BehaviorSubject для этой цели, но выглядит уродливо.Кто может подсказать мне, как это должно быть реализовано с RxSwift ?

class CellViewModel {

    private let selectionSubject = BehaviorSubject<Void>(value: ())

    // Will be used by ListViewModel
    var selectionObservable: Observable<Void> {
        return selectionSubject.asObservable()
    }

    func subscribeOnSelection(_ observable: Observable<Void>, disposeBag: DisposeBag) {
        observable
            .bind(to: selectionSubject)
            .disposed(by: disposeBag)
    }

    private func autoSelect() {
        selectionSubject.on(next: ())
    }
}

class Cell: UITableViewCell {
    @IBOutlet private var selectionButton: UIButton!

    private let disposeBag = DisposeBag()

    func bind(to viewModel: CellViewModel) {
        viewModel.subscribeOnSelection(selectionButton.rx.tap.asObservable(), disposeBag: disposeBag)
    }
}

1 Ответ

0 голосов
/ 30 апреля 2019

Вам нужен объект где-то, потому что источник события не существует, когда создается потребитель события.Обычно я помещаю один предмет в контроллер представления, а не предмет в каждой ячейке.Примерно так:

class Cell: UITableViewCell {
    @IBOutlet private var selectionButton: UIButton!

    private var disposeBag = DisposeBag()

    override func prepareForReuse() {
        super.prepareForReuse()
        disposeBag = DisposeBag()
    }

    func configure(with makeViewModel: (Observable<Void>, DisposeBag) -> Void) {
        makeViewModel(selectionButton.rx.tap.asObservable(), disposeBag)
    }
}

И контроллер вида будет выглядеть примерно так:

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    let disposeBag = DisposeBag()

    var makeViewModel: (Observable<CellID>) -> Observable<[CellID]> = { _ in fatalError() }

    override func viewDidLoad() {
        super.viewDidLoad()

        let cellSelection = PublishSubject<CellID>()

        let cells = makeViewModel(cellSelection)

        cells
            .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: Cell.self)) { index, element, cell in
                cell.configure(with: { selected, disposeBag in
                    selected
                        .map { element }
                        .bind(to: cellSelection)
                        .disposed(by: disposeBag)

                })
                return
            }
            .disposed(by: disposeBag)
    }
}
...