ReactiveCocoa, как прослушивать изменения в свойствах модели данных

Новое в ReactiveCocoa здесь. У меня есть модель представления (MVVM), представляющая страницу, подобную новостной ленте, как правильно прослушивать изменения в свойствах модели данных? В следующем примере startUpdate() постоянно обновляет post. Вычисленные свойства messageToDisplay и shouldShowHeart управляют некоторым событием пользовательского интерфейса.

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 и все вычисляемые свойства? Мне это кажется не совсем правильным.


person Jack Guo    schedule 11.03.2018    source источник


Ответы (1)


Да, вы правы — вам придется прослушивать каждое свойство свойства 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.

В вашем пользовательском интерфейсе (я предполагаю, что это 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()
  }
}
person MeXx    schedule 11.03.2018