如何从 BehaviorRelay observable 更新 tableView?
How can I update tableView from BehaviorRelay observable?
我正尝试在 table 视图中使用油门进行搜索。
这里我在 ViewModel 中有 BehaviorRelay
var countryCodes: BehaviorRelay<[CountryDialElement]> = BehaviorRelay<[CountryDialElement]>(value:[])
这里我有输入文本的 BehaviorRelay
var searchText: BehaviorRelay<String> = BehaviorRelay<String>(value: "")
这里我有 Table 视图,它与视图模型中的 Observable 绑定
self.viewModel.params.countryCodes.bind(to: tableView.rx.items(cellIdentifier: "CountryDialTableViewCell")) { index, model, cell in
let countryCell = cell as! CountryDialTableViewCell
countryCell.configure(model)
}.disposed(by: disposeBag)
这里我有 Rx 绑定到 ViewController
中的 UISearchBar
searchBar
.rx
.text
.orEmpty
.debounce(.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.subscribe { [weak self] query in
guard
let query = query.element else { return }
self?.viewModel.params.searchText.accept(query)
}
.disposed(by: disposeBag)
然后在 ViewModel 中,我尝试过滤数据并将过滤后的数据推送到数据源,以更新 tableView。
Observable.combineLatest(params.countryCodes, params.searchText) { items, query in
return items.filter({ item in
item.name.lowercased().contains(query.lowercased()) || item.dialCode.lowercased().contains(query.lowercased())
})
}.subscribe(onNext: { resultArray in
self.params.countryCodes.accept(resultArray)
})
.disposed(by: disposeBag)
但是我遇到了这种类型的错误
Reentrancy anomaly was detected.
This behavior breaks the grammar because there is overlapping between sequence events.
The observable sequence is trying to send an event before sending the previous event has finished.
Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code, or that the system is not behaving in an expected way.
我正在努力实现:
- 绑定 table 带有可观察数组的视图
- 在搜索栏中输入文字
- 过滤可观察对象,数组
- 更新 observable,重新加载 tableView。
我注意到的第一件事...您有两个定义为 var
的 BehaviorRelay。您应该始终使用 let
.
来定义它们
您没有发布足够的代码来证明错误,但根本问题,如错误消息中向您解释的那样,是您破坏了可观察语法,因为您在中间通过 Observable 推送数据推送数据。如果允许的话,会形成无限递归调用,溢出栈。
在当前事件发送完成之前不要发送事件。如果您不使用那么多中继,将会有很大帮助...
你没有说数组中的项目来自哪里,这也让人很难提供帮助...
考虑这样的事情:
Observable.combineLatest(
searchBar.rx.text.orEmpty
.debounce(.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.startWith(""),
sourceOfItems(),
resultSelector: { searchTerm, items in
items.filter { [=10=].code.contains(searchTerm) }
}
)
.bind(to: tableView.rx.items(cellIdentifier: "CountryDialTableViewCell")) { index, model, cell in
let countryCell = cell as! CountryDialTableViewCell
countryCell.configure(model)
}
.disposed(by: disposeBag)
我正尝试在 table 视图中使用油门进行搜索。
这里我在 ViewModel 中有 BehaviorRelay
var countryCodes: BehaviorRelay<[CountryDialElement]> = BehaviorRelay<[CountryDialElement]>(value:[])
这里我有输入文本的 BehaviorRelay
var searchText: BehaviorRelay<String> = BehaviorRelay<String>(value: "")
这里我有 Table 视图,它与视图模型中的 Observable 绑定
self.viewModel.params.countryCodes.bind(to: tableView.rx.items(cellIdentifier: "CountryDialTableViewCell")) { index, model, cell in
let countryCell = cell as! CountryDialTableViewCell
countryCell.configure(model)
}.disposed(by: disposeBag)
这里我有 Rx 绑定到 ViewController
中的 UISearchBarsearchBar
.rx
.text
.orEmpty
.debounce(.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.subscribe { [weak self] query in
guard
let query = query.element else { return }
self?.viewModel.params.searchText.accept(query)
}
.disposed(by: disposeBag)
然后在 ViewModel 中,我尝试过滤数据并将过滤后的数据推送到数据源,以更新 tableView。
Observable.combineLatest(params.countryCodes, params.searchText) { items, query in
return items.filter({ item in
item.name.lowercased().contains(query.lowercased()) || item.dialCode.lowercased().contains(query.lowercased())
})
}.subscribe(onNext: { resultArray in
self.params.countryCodes.accept(resultArray)
})
.disposed(by: disposeBag)
但是我遇到了这种类型的错误
Reentrancy anomaly was detected.
This behavior breaks the grammar because there is overlapping between sequence events.
The observable sequence is trying to send an event before sending the previous event has finished.
Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code, or that the system is not behaving in an expected way.
我正在努力实现:
- 绑定 table 带有可观察数组的视图
- 在搜索栏中输入文字
- 过滤可观察对象,数组
- 更新 observable,重新加载 tableView。
我注意到的第一件事...您有两个定义为 var
的 BehaviorRelay。您应该始终使用 let
.
您没有发布足够的代码来证明错误,但根本问题,如错误消息中向您解释的那样,是您破坏了可观察语法,因为您在中间通过 Observable 推送数据推送数据。如果允许的话,会形成无限递归调用,溢出栈。
在当前事件发送完成之前不要发送事件。如果您不使用那么多中继,将会有很大帮助...
你没有说数组中的项目来自哪里,这也让人很难提供帮助...
考虑这样的事情:
Observable.combineLatest(
searchBar.rx.text.orEmpty
.debounce(.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.startWith(""),
sourceOfItems(),
resultSelector: { searchTerm, items in
items.filter { [=10=].code.contains(searchTerm) }
}
)
.bind(to: tableView.rx.items(cellIdentifier: "CountryDialTableViewCell")) { index, model, cell in
let countryCell = cell as! CountryDialTableViewCell
countryCell.configure(model)
}
.disposed(by: disposeBag)