web-dev-qa-db-fra.com

Double mappage RxSwift dans tableView.rx.itemSelected

Je veux obtenir un objet de tableView.rx.itemSelected et après le traiter. Cette méthode retourne IndexPath, donc je peux mapper cette valeur. Mais comment obtenir un objet à l'index à partir du ViewModel?

struct ViewModel {
    var items: Observable<[Item]>
}

Je m'attends à quelque chose comme ça (mais ce flux est faux):

tableView.rx.itemSelected
        .map { indexPath -> Item in 
        return viewModel.items.map {$0[indexPath.row]}
        }
        ..subscribe(onNext: { [unowned self] item in
        //other actions with Item object
        })
        .disposed(by: disposeBag)

J'ai montré quelque part cette possibilité, mais je ne m'en souviens pas. Avez-vous une idée de comment le faire?

8
biloshkurskyi.ss

Si vous avez besoin à la fois de indexPath et de model, vous pouvez combiner les 2 méthodes et les transformer en une seule séquence observable:

Observable
    .Zip(tableView.rx.itemSelected, tableView.rx.modelSelected(String.self))
    .bind { [unowned self] indexPath, model in
        self.tableView.deselectRow(at: indexPath, animated: true)
        print("Selected " + model + " at \(indexPath)")
    }
    .disposed(by: disposeBag)
33
Eduard

RxCocoa a 2 méthodes:

public var itemSelected: ControlEvent<IndexPath> { get } Qui renvoie IndexPath de l'élément sélectionné
et
public func modelSelected<T>(_ modelType: T.Type) -> ControlEvent<T> qui renvoie l'élément de modèle
Conformément à votre exemple, il ressemblera à:

    tableView.rx.modelSelected(Item.self)
        .subscribe(onNext: { [weak self] item in
            // other actions with Item object
        }).addDisposableTo(disposeBag)
8
Igor Kotkovets

J'ai également trouvé une autre façon d'ajouter la fonction do(onNext:{...}) après la commande itemSelected:

tableView.rx
    .itemSelected
    .do(onNext: { [unowned self] indexPath in
        self.tableView.deselectRow(at: indexPath, animated: false)
    })
    .map { indexPath -> Item in 
        return viewModel.items.map {$0[indexPath.row]}
    }
    .subscribe(self.viewModel.reviewTimeAction.inputs)
    .disposed(by: disposeBag)
1
biloshkurskyi.ss