Observable, которое наблюдает за BehaviorRelay, вызывающим только один разRxSwift - PullRequest
2 голосов
/ 19 октября 2019

У меня есть parentView, который содержит два разных CollectionViwes. Каждое представление заполняется из базы данных путем передачи данных в Observable с использованием BehaviorRelay. Все работает нормально, пока мне не придется обновлять Views в collection_view_2 из collection_view_1. То, что я делаю, передает BehaviorRelay извлеченные данные, как я делаю ранее в том же ParentView. Но я вижу, что на этот раз при нажатии collection_view_1's ячейки Observable из StudentCell не вызывается. Я не могу понять, почему так происходит. Я видел другие вопросы SO, но ни у кого нет ответа, чтобы это исправить. Посмотрите на приведенный ниже код для лучшего понимания.

Collection_view_1

class ClassTabCV: UIViewController, UICollectionViewDelegateFlowLayout {
    let classCells = BehaviorRelay<[ClassModel]>(value: [])
    let pickupVC = PickUpViewController()

    override func viewDidLoad() {
        super.viewDidLoad()
        classTab.rx.setDelegate(self).disposed(by: disposeBag)
        setupBinding()
    }

    func setupBinding() {
        classTab.register(UINib(nibName: "ClassTabCVCell", bundle: nil), forCellWithReuseIdentifier: "classTabCV")
        //Cell creation
        classCells.asObservable().debug("Class View: ").bind(to: classTab.rx.items(cellIdentifier: "classTabCV", cellType: ClassTabCVCell.self)) {[weak self]
            (row , element, cell) in
            cell.viewModel = element
            }.disposed(by: disposeBag)

        // item selection with model details.
        Observable
            .zip(
                classTab
                    .rx
                    .itemSelected,
                classTab
                    .rx
                    .modelSelected(ClassModel.self))
            .bind { [weak self] indexPath, model in
                self?.pickupVC.getStudentsData2(id: model.classId) // here I am trying to pass reference to update Collection_view_2 views.

            }.disposed(by: disposeBag)
    }
}

Collection_view_2

class StudentCV: UIViewController, UICollectionViewDelegateFlowLayout {


    let studentCells = BehaviorRelay<[StudentModel]>(value: [])
    var dataSource = RxCollectionViewSectionedAnimatedDataSource<SectionViewModel>(configureCell: {( _,_,_,_ ) in
        fatalError()
    })
    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        studentsView.rx.setDelegate(self).disposed(by: disposeBag)
        setupBinding()
    }

    func setupBinding() {

        dataSource.configureCell = { (ds, cv, ip, item) in

            let cell = cv.dequeueReusableCell(withReuseIdentifier: "studentCV", for: ip) as! StudentCVCell
            cell.viewModel = item
            return cell
        }
            studentCells
                .asObservable()
                .debug("Student View: ")
                .map({ [SectionViewModel(header: "", items: $0.filter({$0.pickupStatus == 2}) ), SectionViewModel(header: "", items: $0.filter({$0.pickupStatus == 3}) )] })
                .bind(to: studentsView.rx.items(dataSource: dataSource))
                .disposed(by: disposeBag)
    }
}

ParentView_Controller

    let studentCells = BehaviorRelay<[StudentModel]>(value: [])
    let classCells = BehaviorRelay<[ClassModel]>(value: [])

    var studentCell : Observable<[StudentModel]> {
        return studentCells.asObservable().debug("IS DATA IN: ")
    } // this observable is not calling the time I pass reference from Collection_View_1 on tap.
    var classCell : Observable<[ClassModel]> {
        return classCells.asObservable()
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        getAssignedClassData(classId: id)
        self.getStudentsData(id: id)
        bindViewModel()
    }

    func getStudentsData(id: Int) {


    let studentsData = Database.singleton.fetchStudents(byCLassId: id)
                self!.studentCells.accept(Array(studentsData))

        let classData = Database.singleton.fetchClass()
                self!.classCells.accept(Array(classData))

    }
    func getStudentsData2(id: Int) {

        let studentsData = Database.singleton.fetchStudents(byCLassId: id)
                self!.studentCells.accept(Array(studentsData)) // when this calls, observer is not emitting anything. 

    }

    func bindViewModel() {
        self
            .studentCell
            .asObservable()
            .debug("BIND: ")
            .observeOn(MainScheduler.instance)
            .bind(to: studentsViewController.studentCells)
            .disposed(by: disposeBag)

        self
            .classCell
            .asObservable()
            .debug("CELL BIND: ")
            .observeOn(MainScheduler.instance)
            .bind(to: classViewController.classCells)
            .disposed(by: disposeBag)
    }

При нажатии collection_view_1. Collection_view_2 должен обновить данные. и измените взгляды соответственно. Я делаю то же самое с другой точки зрения, но разница есть. collectionView получает ссылку на изменение из buttonClick, а не из любого другого CollectionView. Любая помощь, исправляющая мою проблему, будет оценена. Спасибо

...