首页 文章

RxSwift正确的订阅数据模型属性更改方式

提问于
浏览
2

这里是RxSwift的新手 . 我有一个(MVVM)视图模型,它代表一个类似于Newsfeed的页面,_685308的属性是什么?在以下示例中, 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 ?这对我来说不太合适 .

1 回答

  • 0

    //类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 ..你可以使用许多方法和属性 .

相关问题