New to ReactiveCocoa here. I have a (MVVM) view model that represents a Newsfeed-like page, what's the correct way to listen to change in data model's properties? In the following example, startUpdate()
constantly updates post
. The computed properties messageToDisplay
and shouldShowHeart
drives some UI event.
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
}
...
}
It seems to me in order to make this whole thing reactive, I have to listen to each properties of Post
and all computed properties? It doesn't look quite right to me.
Yes, you are right - you will have to listen to each property property of Post
that you want to bind to the UI, but that is actually not that big of a deal.
I suggest you use ReactiveSwift Property
and replace the computed properties like so:
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
}
}
}
The only thing you change is the post (with each update of the post), hence that is a MutableProperty
, but it is private and can only be changed by the PostViewModel
.
The computed properties are replaced by Property
(which are read-only) and since they derive their value from a post, they are mapped from the post MutableProperty
In your UI (I assume its a UITableViewCell for each post) you can bind these properties like this:
class PostTableViewCell: UITableViewCell {
var message: UILabel!
var heartIcon: UIImageView!
func bind(post: PostViewModel) {
message.reactive.text <~ post.messageToDisplay
heartIcon.reactive.isHidden <~ post.shouldShowHeart.negate()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.