• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - RxSwift 订阅数据模型属性更改的正确方法

[复制链接]
菜鸟教程小白 发表于 2022-12-11 19:50:43 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

这里是 RxSwift 的新手。我有一个(MVVM) View 模型,它代表一个类似新闻源的页面,订阅数据模型属性更改的正确方法是什么?在以下示例中,startUpdate() 不断更新 post。计算的属性 messageToDisplayshouldShowHeart 驱动一些 UI 事件。

struct Post {
    var iLiked: Bool
    var likes: Int
    ...
}

class PostViewModel: NSObject {
    private var post: Post

    var messageToDisplay: String {
        if post.iLiked { return ... }
        else { return .... }
    }

    var shouldShowHeart: Bool {
        return iLiked && likes > 10
    }

    func startUpdate() {
        // network request and update post
    }
    ...
}

在我看来,为了使整个事情具有反应性,我必须将 Post 的每个属性和所有计算属性都转换为 Variable?我觉得不太对劲。



Best Answer-推荐答案


//类 NetworkRequest 或任何名称

static func request(endpoint: String, query: [String: Any] = [:]) -> Observable<[String: Any]> {
    do {
        guard let url = URL(string: API)?.appendingPathComponent(endpoint) else {
            throw EOError.invalidURL(endpoint)
        }

        return manager.rx.responseJSON(.get, url)
            .map({ (response, json) -> [String: Any] in
                guard let result = json as? [String: Any] else {
                    throw EOError.invalidJSON(url.absoluteString)
                }
                return result
            })
      } catch {
        return Observable.empty()
      }
}

static var posts: Observable<[Post]> = {
    return NetworkRequest.request(endpoint: postEndpoint)
        .map { data in
            let posts = data["post"] as? [[String: Any]] ?? []
            return posts
                .flatMap(Post.init)
                .sorted { $0.name < $1.name }
        }
        .shareReplay(1)
}()


class PostViewModel: NSObject {
    let posts = Variable<[Post]>([])
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
      super.viewDidLoad()

      posts
       .asObservable()
       .subscribe(onNext: { [weak self] _ in
         DispatchQueue.main.async {
            //self?.tableView?.reloadData() if you want to reload all tableview
            self.tableView.insertRows(at: [IndexPath], with: UITableViewRowAnimation.none) // OR if you want to insert one or multiple rows.
            //OR update UI
         }
      })
      .disposed(by: disposeBag)



      posts.asObservable()
     .bind(to: tableView.rx.items) { [unowned self] (tableView: UITableView, index: Int, element: Posts) in
        let cell = tableView.dequeueReusableCell(withIdentifier: "postCell") as! PostCell
//for example you need to update the view model and cell with textfield.. if you want to update the ui with a cell then use cell.button.tap{}. hope it works for you.
        cell.textField.rx.text
            .orEmpty.asObservable()
            .bind(to: self.posts.value[index].name!)
            .disposed(by: cell.disposeBag)
        return cell
    }

      startDownload()
  }
}

func startDownload {
    posts.value = NetworkRequest.posts
}

如果您想更改任何内容,请使用 subscribe、bind、concat .. 您可以使用许多方法和属性。

关于ios - RxSwift 订阅数据模型属性更改的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49212915/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap