RxCocoa-observable 正在从 API 发出新数据,但 tableview.rx.items 不显示新数据
Posted
技术标签:
【中文标题】RxCocoa-observable 正在从 API 发出新数据,但 tableview.rx.items 不显示新数据【英文标题】:RxCocoa-observable is emitting new data from API but tableview.rx.items doesn't show new data 【发布时间】:2018-10-17 10:00:05 【问题描述】:我是 RxSwift 和 RxCocoa 的新手。
我在本地有一个可用的 REST 服务,它为给定的“id”返回一个电影对象。
在我的故事板上有一个 tableView (UITableView),它有自定义单元格 (MovieCell)。每个电影单元格都有一个名为“nameTextLabel”的 UILabel。我还有一个 textField 可以从用户那里获取请求的 movie.id。
我正在尝试在 tableView 的每一行上显示 movie.title。
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController
@IBOutlet var textField: UITextField!
@IBOutlet var tableView: UITableView!
let bag = DisposeBag()
override func viewDidLoad()
super.viewDidLoad()
configureReactiveBinding()
private func configureReactiveBinding()
textField.rx.text.asObservable()
.map ($0 == "" ? "15" : $0!).lowercased()
.map GetMovieByIdRequest(id: $0)
.flatMap request -> Observable<Movie> in
return ServiceManager.instance.send(apiRequest: request)
.debug("movie")
// output:
//2018-10-17 16:13:49.320: movie -> subscribed
//2018-10-17 16:13:49.401: movie -> Event next(MovieAdvisor.Movie)
//2018-10-17 16:13:52.021: movie -> Event next(MovieAdvisor.Movie)
.toArray()
.debug("tableView")
// output:
//2018-10-17 16:13:49.318: tableView -> subscribed
.bind(to: tableView.rx.items(cellIdentifier: "movie_cell", cellType:MovieCell.self)) index, model, cell in
cell.nameTextLabel.text = model.title
.disposed(by: bag)
每次更改 textLabel 时都会打印新的 movie.id,但 tableView 不显示任何数据——即使是初始值也不显示(当 textField 为 "" 时)。
知道如何解决这个问题吗?
添加 debug() 行后,我发现 tableView 只订阅了一次,并且没有下一个事件触发 tableView。我该怎么办? 代码上传到 GitHub github
【问题讨论】:
????我需要一些信息来帮助您...在您的.toArray()
和您的.bind(to:)
之间添加一个.debug("tableView")
。将该调试语句的输出添加到您的问题中。
感谢您的快速回复!添加了调试命令,希望对您解决问题有所帮助。
【参考方案1】:
问题在于您的toArray()
运算符。该操作符一直等到序列完成,然后将整个序列作为单个数组发出。在您退出视图控制器之前,您的序列不会完成。
将其替换为 .map [$0]
即可显示电影。您应该问问自己,为什么您的端点只返回一部电影而不是一组电影。
【讨论】:
当我用 .map [$0] 替换 toArray() 时,我得到“无法推断通用参数自身”编译时错误。我的端点只返回 1 部电影的原因是,因为它是 getMovieById,所以它只返回具有给定 id 的电影。你为什么这么建议?使用 Observables 时使用数组会更好吗? 奇怪,我下载了你的 GitHub 项目并进行了替换,它运行良好。一个 tableview 显示一个数组,这就是为什么我很惊讶提供 tableview 的流只发出一个值。【参考方案2】:尝试替换
`a.subscribe(onNext: movie in
print(movie.title)
)
.disposed(by: bag)
用.observeOn(MainScheduler.instance)
看看它是否有效。
也许将.toArray()
直接移动到ServiceManager.instance.send(apiRequest: request)
之后。
您还可以在每个 RxSwift 运算符之后添加 *.debug("my custom message")*
以查看它是否正在执行。
顺便说一句,我建议为此使用 RxDataSources 框架,而不是裸露的 RxCocoa。
【讨论】:
感谢 debug() 建议。观察主调度器并没有帮助:( 也许将 '.toArray()' 直接移动到 'ServiceManager.instance.send(apiRequest: request)' 之后 我做到了,谢谢!其背后的原因是.toArray()
等待整个事情完成(这永远不会发生),但您需要它在每次服务请求后发出。以上是关于RxCocoa-observable 正在从 API 发出新数据,但 tableview.rx.items 不显示新数据的主要内容,如果未能解决你的问题,请参考以下文章