ReactiveCocoa如何监听数据模型属性的变化

时间:2018-03-11 01:51:22

标签: ios swift mvvm reactive-cocoa reactive-swift

这里是ReactiveCocoa的新手。我有一个(MVVM)视图模型,它代表一个类似于新闻源的页面,听取数据模型属性变化的正确方法是什么?在以下示例中,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的所有属性和所有计算属性?它对我来说并不合适。

1 个答案:

答案 0 :(得分:1)

是的,你是对的 - 你必须要监听你想要绑定到UI的Post的每个属性属性,但实际上这并不是什么大不了的事。

我建议您使用ReactiveSwift Property并替换计算属性,如下所示:

final class PostViewModel {
  private let post: MutableProperty<Post>

  let messageToDisplay: Property<String>
  let shouldShowHeart: Property<Bool>

  func startUpdate() {
    // network request and update post by setting self.post.value = newPost
  }

  init(post: Post) {
    self.post = MutableProperty(post)
    self.messageToDisplay = self.post.map {
      if $0.iLiked { return "liked" }
      else { return "not liked" }
    }
    self.shouldShowHeart = self.post.map {
      $0.iLiked && $0.likes > 10
    }
  }
}

您唯一更改的是帖子(每次更新帖子),因此这是MutableProperty,但它是私有的,只能由PostViewModel更改。

计算的属性由Property(只读)替换,因为它们从帖子中获取值,所以它们是从帖子MutableProperty

映射的

在你的UI中(我假设每个帖子都有一个UITableViewCell)你可以像这样绑定这些属性:

class PostTableViewCell: UITableViewCell {
  var message: UILabel!
  var heartIcon: UIImageView!

  func bind(post: PostViewModel) {
    message.reactive.text <~ post.messageToDisplay
    heartIcon.reactive.isHidden <~ post.shouldShowHeart.negate()
  }
}