菜鸟教程小白 发表于 2022-12-11 19:50:43

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


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

<pre><code>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 &amp;&amp; likes &gt; 10
    }

    func startUpdate() {
      // network request and update post
    }
    ...
}
</code></pre>

<p>在我看来,为了使整个事情具有反应性,我必须将 <code>Post</code> 的每个属性和所有计算属性都转换为 <code>Variable</code>?我觉得不太对劲。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>//类 NetworkRequest 或任何名称</p>

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

      return manager.rx.responseJSON(.get, url)
            .map({ (response, json) -&gt; in
                guard let result = json as? else {
                  throw EOError.invalidJSON(url.absoluteString)
                }
                return result
            })
      } catch {
      return Observable.empty()
      }
}

static var posts: Observable&lt;&gt; = {
    return NetworkRequest.request(endpoint: postEndpoint)
      .map { data in
            let posts = data[&#34;post&#34;] as? [] ?? []
            return posts
                .flatMap(Post.init)
                .sorted { $0.name &lt; $1.name }
      }
      .shareReplay(1)
}()


class PostViewModel: NSObject {
    let posts = Variable&lt;&gt;([])
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
      super.viewDidLoad()

      posts
       .asObservable()
       .subscribe(onNext: { _ in
         DispatchQueue.main.async {
            //self?.tableView?.reloadData() if you want to reload all tableview
            self.tableView.insertRows(at: , 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) { (tableView: UITableView, index: Int, element: Posts) in
      let cell = tableView.dequeueReusableCell(withIdentifier: &#34;postCell&#34;) 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.name!)
            .disposed(by: cell.disposeBag)
      return cell
    }

      startDownload()
}
}

func startDownload {
    posts.value = NetworkRequest.posts
}
</code></pre>

<p>如果您想更改任何内容,请使用 subscribe、bind、concat .. 您可以使用许多方法和属性。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - RxSwift 订阅数据模型属性更改的正确方法,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/49212915/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/49212915/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - RxSwift 订阅数据模型属性更改的正确方法