首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >RxSwift + MVVM:将传入模型映射到公开的驱动程序/可观察属性的有效方法

RxSwift + MVVM:将传入模型映射到公开的驱动程序/可观察属性的有效方法
EN

Stack Overflow用户
提问于 2017-02-13 02:24:35
回答 1查看 919关注 0票数 0

我正在使用RxSwift绑定视图模型和视图,并且我有大约10个驱动程序在我的视图模型中公开属性:

代码语言:javascript
代码运行次数:0
运行
复制
let title: Driver<String>
let description: Driver<String>
let price: Driver<String>
...

从传入的模型序列中驱动这些可观测数据的最佳方法是什么?观察每个司机的到来是最好的吗?这是一种奇怪/低效的做事方式吗?

代码语言:javascript
代码运行次数:0
运行
复制
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: "")
...

除了创建私有变量,订阅可观察模型,在每个下一个事件上设置变量,然后必须从变量创建另一组公共驱动程序/可观察对象之外,我想不出更好的方法来完成这项工作,即:

代码语言:javascript
代码运行次数:0
运行
复制
let titleDriver: Driver<String>
private let title = Variable<String>("")
...
titleDriver = title.asDriver()

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

我希望确保我不会从视图模型外部公开Variable,因为您不希望任何人使用它们!

EN

回答 1

Stack Overflow用户

发布于 2017-02-13 03:27:03

我没有尝试过,但我会这样做:

您的模型:

代码语言:javascript
代码运行次数:0
运行
复制
struct Product {
    let title: String
    let description: String
    let price: String
    // ...
}

然后,我将使用不同的UILabel (或UIWhateverYouWant)创建一个UIView子类。

代码语言:javascript
代码运行次数:0
运行
复制
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)
    }

}

和一个扩展:

代码语言:javascript
代码运行次数:0
运行
复制
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的引用。例如:

代码语言:javascript
代码运行次数:0
运行
复制
class viewController: UIViewController {
    @IBOutlet private weak var detailView: ProductDetailView!
    // ...

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

    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42191460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档