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