2017-02-12 16 views
0

我使用RxSwift绑定视图模型和视图,和我有大约10名司机,在我的视图模型暴露属性:RxSwift + MVVM:高效的方式进入地图模式,暴露的驱动器/可观察性

let title: Driver<String> 
let description: Driver<String> 
let price: Driver<String> 
... 

从传入的模型序列中驱动这些观测量的最佳方法是什么?是否最好观察每个驾驶员的来电?这是一种奇怪/无效的做事方式吗?

self.title = incoming.productObservable.map({ $0.title }).asDriver(onErrorJustReturn: "") 
self.description = incoming.productObservable.map({ $0.description }).asDriver(onErrorJustReturn: "") 
self.price = incoming.productObservable.map({ $0.price }).asDriver(onErrorJustReturn: "") 
... 

我想不出这样做比创建私有变量,订阅观察的模型,每一个事件设置变量,然后另外创建一套公共驱动器的其它更好的方式/来自变量的观察值,即:

let titleDriver: Driver<String> 
private let title = Variable<String>("") 
... 
titleDriver = title.asDriver() 

但我讨厌每个属性所需的代码的重复和数量!

我想确保我不会从视图模型外部暴露Variable,因为您不希望任何人与他们一起玩耍!

+0

您是否想要将模型属性与'viewController'中的'UILabel'绑定? – XFreire

回答

0

我没有尝试,但我会做这样的事情:

你的模型:

struct Product { 
    let title: String 
    let description: String 
    let price: String 
    // ... 
} 

然后,我将创建一个子类UIView用型动物UILabel(或UIWhateverYouWant)。

final class ProductDetailView: UIView { 

    // MARK: - Properties 
    var product: Product? { 
     didSet { 
      didSetProduct() 
     } 
    } 

    fileprivate var titleLabel = UILabel() 
    fileprivate var descriptionLabel = UILabel() 
    fileprivate var priceLabel = UILabel() 
    // ... 

    fileprivate var disposeBag = DisposeBag() 

    // MARK: - Initialization 
    init() { 
     super.init(frame: CGRect.zero) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

} 

而且一个延伸:

private extension ProductDetailView { 

    func didSetProduct() { 
     guard let product = product else { return } 
     // Bind the result to our observer property 
     Observable.just(product) 
      .bindTo(productObserver) 
      .addDisposableTo(disposeBag) 

    } 

    /// A bindable observer for product 
    var productObserver: AnyObserver<Product> { 

     return UIBindingObserver(UIElement: self) { detailView, product in 

      detailView.titleLabel.text = product.title 
      detailView.descriptionLabel.text = product.description 
      detailView.priceLabel.text = product.price 

     }.asObserver() 
    } 
} 

viewModel将有一个Observable<Product>属性(或Driver<Product>

最后,在你的viewController你将不得不ProductDetailView参考。例如:

class viewController: UIViewController { 
    @IBOutlet private weak var detailView: ProductDetailView! 
    // ... 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     viewModel.product 
      .bindTo(detailView.productObserver) 
      .addDisposableTo(db) 

    } 
}