0

这里是 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和所有计算属性?我看起来不太对劲。

4

1 回答 1

1

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

我建议你使用 ReactiveSwiftProperty并像这样替换计算的属性:

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
    }
  }
}

您唯一更改的是帖子(每次更新帖子),因此它是 a 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()
  }
}
于 2018-03-11T10:13:54.213 回答