ios - 如何从 BehaviorRelay observable 更新 tableView?
问题描述
我正在尝试使用油门在表格视图中进行搜索。
在这里,我在 ViewModel 中有 BehaviorRelay
var countryCodes: BehaviorRelay<[CountryDialElement]> = BehaviorRelay<[CountryDialElement]>(value:[])
在这里,我有输入文本的 BehaviorRelay
var searchText: BehaviorRelay<String> = BehaviorRelay<String>(value: "")
在这里,我有与 View Model 中的 Observable 绑定的 Table View
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 中,我尝试过滤数据并将过滤后的数据推送到 dataSource,以更新 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.
我正在努力实现:
- 带有可观察数组的绑定表视图
- 在搜索栏中输入文本
- 过滤可观察对象,数组
- 更新 observable,重新加载 tableView。
解决方案
我注意到的第一件事......你有两个 BehaviorRelays 定义为var
. 您应该始终使用 定义它们let
。
您没有发布足够的代码来演示该错误,但正如错误消息中向您解释的那样,根本问题是您正在破坏 observable 语法,因为您在推送数据的过程中通过 Observable 推送数据。如果允许,它将形成一个无限递归调用,该调用会溢出堆栈。
在当前事件完成发送之前不要发送事件。如果您不使用这么多继电器,那将有很大帮助...
你没有说数组中的项目来自哪里,这也很难帮助......
考虑这样的事情:
Observable.combineLatest(
searchBar.rx.text.orEmpty
.debounce(.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.startWith(""),
sourceOfItems(),
resultSelector: { searchTerm, items in
items.filter { $0.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)
推荐阅读
- sql-server - 删除后,UPDATE 触发器在 SQL 中无法正常工作
- python - 使用 functools.wraps 在装饰器链中保留精确的函数签名
- swift - How to check multiply results in unit testing Swift?
- vb.net - 从列表中选择不同的值
- java - 如何解析这个特定的日期数据?
- javascript - 从 aws s3 存储桶动态更改文件的列名
- python-3.x - 如何通过服务 url 提供图像,这些图像从谷歌计算引擎上传到谷歌云存储
- mysql - Mysql从多列计数?
- javascript - 在 Vue.js 中更新变量的问题
- visual-studio-2013 - 并行工作室不适用于 Visual Studio 2013