当我使用 RxDatasources 更新数据源时,不会触发 configureCell

Posted

技术标签:

【中文标题】当我使用 RxDatasources 更新数据源时,不会触发 configureCell【英文标题】:configureCell is not triggered when I update a datasource using RxDatasources 【发布时间】:2021-12-24 18:09:52 【问题描述】:

我的视图模型中有一个行为中继,用作数据源。它的定义是这样的:

var posts: BehaviorRelay<[PostModel]>

它是通过网络用数据初始化的,当我绑定数据时它会正常初始化tableView。

现在,如果我尝试更改此处帖子的点赞状态,就像这样(这也在我的视图模型中):

private func observeLikeStatusChange() 
        
        self.changedLikeStatusForPost
            .withLatestFrom(self.posts, resultSelector:  ($1, $0) )
            .map (posts, changedPost) -> [PostModel] in
                //...
                var editedPosts = posts
                editedPosts[index] = changedPost // here data is correct, index, changedContact
                return editedPosts
            
            .bind(to: self.posts)
            .disposed(by: disposeBag)
    

因此,没有任何反应。如果我从 editedPosts 中删除元素,tableView 会正确更新并删除该行。

PostModel struct 符合Equatable,它要求所有属性此时都相同。

在我的视图控制器中,我创建这样的数据源:

tableView.rx.setDelegate(self).disposed(by: disposeBag)
 let dataSource = RxTableViewSectionedAnimatedDataSource<PostsSectionModel>(
            configureCell:  dataSource, tableView, indexPath, item in
             //...
                return postCell
            )
        
        postsViewModel.posts
            .map( posts in
                let models = posts.map PostCellModel(model: $0) 
                return [PostsSectionModel(model: "", items: models)]
            ) // If I put debug() here, this is triggered and I get correct section model with correct values
            .bind(to: self.tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)

所以,正如我所说,我得到了正确的值,但 configureCell 没有被触发。我在这里做错了什么?

编辑:

这里是 PostCellModel:

导入基础

import RxDataSources

typealias PostsSectionModel = AnimatableSectionModel<String, PostCellModel>


struct PostCellModel : Equatable, IdentifiableType 
    
    static func == (lhs: PostCellModel, rhs: PostCellModel) -> Bool 
        
        return lhs.model.id == rhs.model.id
    
    
    var identity: Int 
        return model.id
    
    var model: PostModel

还有一个 PostModel:

 struct PostModel: Codable, CellDataModel, Equatable 
    static func == (lhs: PostModel, rhs: PostModel) -> Bool 
       return
        lhs.liked == rhs.liked &&
        rhs.title == lhs.title &&
        
        lhs.location == rhs.location &&
        lhs.author == rhs.author &&
       
        lhs.created == rhs.created
    
    
    let id: Int
    let title: String
    let location: String?
    let author: String
    let created: Int
    let liked:Bool

【问题讨论】:

PostModelPostsSectionModel 是如何定义的? @DanielT。您好,抱歉回复晚了。我添加了PostModelPostsSectionModel。还有PostCellModel 【参考方案1】:

您在 PostCellModel 中错误地定义了 Equatable 一致性。因此,系统无法判断单元模型是否已更改...删除您手动定义的==(lhs:rhs:) 并让系统为您生成它们,您应该没问题...

typealias PostsSectionModel = AnimatableSectionModel<String, PostCellModel>

struct PostCellModel : Equatable, IdentifiableType 
    var identity: Int 
        return model.id
    
    var model: PostModel


struct PostModel: Codable, CellDataModel, Equatable 
    let id: Int
    let title: String
    let location: String?
    let author: String
    let created: Int
    let liked:Bool

【讨论】:

很高兴它成功了,这里有更多关于为什么...底层系统使用== 来判断两个具有相同identity 的对象是否确实不同。如果不是,它不会取代它们。由于您的== 仅比较身份,因此系统不知道模型已更改值。

以上是关于当我使用 RxDatasources 更新数据源时,不会触发 configureCell的主要内容,如果未能解决你的问题,请参考以下文章

RxDataSources`无法推断通用参数'Self'`

RxSwift 使 Observable 触发一个主题

当我想使用 db-migration 更新数据库时,如何防止数据丢失?

当我更新现有数据时 System.Reflection.TargetException ERROR

当我尝试从 firebase 更新数据时出错

在Laravel中,当我直接用数据库更新内容时,我怎样才能保持搜索索引有正确的数据更新?